p80211req.c
来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 438 行
C
438 行
/* src/p80211/p80211req.c** Request/Indication/MacMgmt interface handling functions** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.* --------------------------------------------------------------------** linux-wlan** The contents of this file are subject to the Mozilla Public* License Version 1.1 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.mozilla.org/MPL/** Software distributed under the License is distributed on an "AS* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** Alternatively, the contents of this file may be used under the* terms of the GNU Public License version 2 (the "GPL"), in which* case the provisions of the GPL are applicable instead of the* above. If you wish to allow the use of your version of this file* only under the terms of the GPL and not to allow others to use* your version of this file under the MPL, indicate your decision* by deleting the provisions above and replace them with the notice* and other provisions required by the GPL. If you do not delete* the provisions above, a recipient may use your version of this* file under either the MPL or the GPL.** --------------------------------------------------------------------** Inquiries regarding the linux-wlan Open Source project can be* made directly to:** AbsoluteValue Systems Inc.* info@linux-wlan.com* http://www.linux-wlan.com** --------------------------------------------------------------------** Portions of the development of this software were funded by * Intersil Corporation as part of PRISM(R) chipset product development.** --------------------------------------------------------------------** This file contains the functions, types, and macros to support the* MLME request interface that's implemented via the device ioctls.* * --------------------------------------------------------------------*//*================================================================*//* System Includes */#define __NO_VERSION__ /* prevent the static definition */#include <linux/config.h>#include <linux/version.h>#include <wlan/wlan_compat.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/skbuff.h>#include <linux/slab.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <net/sock.h>#include <linux/netlink.h>/*================================================================*//* Project Includes */#include <wlan/version.h>#include <wlan/p80211types.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/p80211conv.h>#include <wlan/p80211msg.h>#include <wlan/p80211netdev.h>#include <wlan/p80211ioctl.h>#include <wlan/p80211metadef.h>/*================================================================*//* Local Constants *//* Maximum amount of time we'll wait for a request to complete */#define P80211REQ_MAXTIME 3*HZ /* 3 seconds *//*================================================================*//* Local Macros *//*================================================================*//* Local Types */typedef void (*timerfunc_t)(unsigned long);/*================================================================*//* Local Static Definitions *//* Netlink interface(s) */static struct sock *nl_indicate = NULL;/*================================================================*//* Local Function Declarations */static void p80211req_timerfunc(wlandevice_t *wlandev);static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg);#ifdef CONFIG_NETLINKstatic void p80211ind_rx(struct sock *sk, int len);#endif/*================================================================*//* Function Definitions *//*----------------------------------------------------------------* p80211req_dorequest** Handles an MLME reqest/confirm message.* * Arguments:* wlandev WLAN device struct* msgbuf Buffer containing a request message** Returns: * 0 on success, an errno otherwise* * Call context:* Potentially blocks the caller, so it's a good idea to * not call this function from an interrupt context.----------------------------------------------------------------*/int p80211req_dorequest( wlandevice_t *wlandev, UINT8 *msgbuf){ int result = 0; int retval; p80211msg_t *msg = (p80211msg_t*)msgbuf; DBFENTER; /* Check to make sure the MSD is running */ if ( !((wlandev->msdstate == WLAN_MSD_HWPRESENT && msg->msgcode == DIDmsg_lnxreq_ifstate) || wlandev->msdstate == WLAN_MSD_RUNNING || wlandev->msdstate == WLAN_MSD_FWLOAD) ) { return -ENODEV; } /* Check for busy status */ if ( test_and_set_bit(1, &(wlandev->request_pending))) { return -EBUSY; } wlandev->curr_msg = msg; /* Allow p80211 to look at msg and handle if desired. */ /* So far, all p80211 msgs are immediate, no waitq/timer necessary */ /* This may change. */ p80211req_handlemsg(wlandev, msg); /* Pass it down to wlandev via wlandev->mlmerequest */ if ( wlandev->mlmerequest != NULL ) { retval = (*(wlandev->mlmerequest))(wlandev, msg); if (retval < 0) { /* wlandev is still chewing on it, time to block */ /* set up wait_q and timeout */ init_timer(&wlandev->reqtimer); wlandev->reqtimer.data = (unsigned long)wlandev; wlandev->reqtimer.function = (timerfunc_t)p80211req_timerfunc; wlandev->reqtimer.expires = jiffies + P80211REQ_MAXTIME; add_timer(&wlandev->reqtimer); /* Now, do an interruptible_sleep, */ /* we'll be awakened by: a signal to the process, */ /* cmdtimerfunc (timeout), or p80211req_confirm */ interruptible_sleep_on(&(wlandev->reqwq)); /* If sleep return is via signal */ if ( signal_pending(current) ) { WLAN_LOG_DEBUG0(2,"req unblocked via signal\n"); /* stop request, clean up */ del_timer(&wlandev->reqtimer); result = -EINTR; } else { /* If timeout */ if ( wlandev->reqtimer.expires == 0 ) { WLAN_LOG_DEBUG0(2, "req unblocked via timeout\n"); /* stop request, clean up request */ result = -ETIME; } else { /* Success, clean up timer */ del_timer(&wlandev->reqtimer); wlandev->reqtimer.expires=0; result = 0; } } } else { result = -retval; /* retval shld be a positive errno */ } } wlandev->curr_msg = NULL; clear_bit( 1, &(wlandev->request_pending)); DBFEXIT; return result; /* if result==0, msg->status still may contain an err */}/*----------------------------------------------------------------* p80211req_timerfunc** Timer function for request timeouts.* * Arguments:* wlandev WLAN device struct** Returns: * nothing* * Call context:* Timer interrupt----------------------------------------------------------------*/void p80211req_timerfunc(wlandevice_t *wlandev){ wlandev->reqtimer.expires = 0; if (wlandev->request_pending != 0) { wake_up_interruptible(&(wlandev->reqwq)); }}/*----------------------------------------------------------------* p80211req_handlemsg** p80211 message handler. Primarily looks for messages that* belong to p80211 and then dispatches the appropriate response.* TODO: we don't do anything yet. Once the linuxMIB is better* defined we'll need a get/set handler. * * Arguments:* wlandev WLAN device struct* msg message structure** Returns: * nothing (any results are set in the status field of the msg)* * Call context:* Process thread----------------------------------------------------------------*/void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg){ return;}/*----------------------------------------------------------------* p80211req_confirm** Called by the MSD when an asynch request is finished. Our* primary job here is to unblock the _dorequest function above.* * Arguments:* wlandev WLAN device struct** Returns: * nothing* * Call context:* Any----------------------------------------------------------------*/void p80211req_confirm(wlandevice_t *wlandev){ DBFENTER; if ( wlandev->request_pending != 0 ){ wake_up_interruptible(&(wlandev->reqwq)); } DBFEXIT; return;}#ifdef CONFIG_NETLINK/*----------------------------------------------------------------* p80211indicate_init** Called during the p80211 startup to set up the netlink interfaces* for sniffing and indication messages.* * Arguments:* none** Returns: * nothing* * Call context:* Any----------------------------------------------------------------*/void p80211indicate_init(void){ DBFENTER; nl_indicate = netlink_kernel_create( P80211_NL_SOCK_IND, &p80211ind_rx); if ( nl_indicate == NULL ) { WLAN_LOG_DEBUG0(2,"Failed to create indicate netlink i/f.\n"); } DBFEXIT; return;}/*----------------------------------------------------------------* p80211indicate_shutdown** Called during the p80211 unload to get rid of our netlink * interface.* * Arguments:* none** Returns: * nothing* * Call context:* Any----------------------------------------------------------------*/void p80211indicate_shutdown(void){ struct sock *nl; DBFENTER; nl = nl_indicate; nl_indicate = NULL; if ( nl != NULL && nl->socket != NULL) { sock_release(nl->socket); } DBFEXIT; return;}/*----------------------------------------------------------------* p80211ind_rx** Called by netlink when a message comes down. We currently don't* support message from userland via netlink, so this is a empty* function.* * Arguments:* sk netlink sock* len msg len** Returns: * nothing* * Call context:* Any----------------------------------------------------------------*/void p80211ind_rx(struct sock *sk, int len){ return;}/*----------------------------------------------------------------* p80211ind_mlme** Called by the MSD to deliver an mlme type indication message.* * Arguments:* wlandev WLAN device struct* skb skb containing message to deliver** Returns: * nothing* * Call context:* Any----------------------------------------------------------------*/void p80211ind_mlme( wlandevice_t *wlandev, struct sk_buff *skb){ DBFENTER; if ( nl_indicate != NULL ) {/* TODO: Look at queuing mlme indications when requests are pending. */ netlink_broadcast(nl_indicate, skb, 0, P80211_NL_MCAST_GRP_MLME, GFP_ATOMIC); } else { WLAN_LOG_DEBUG0(2,"Can't send indicate msg, no netlink i/f\n"); } DBFEXIT; return;}/*----------------------------------------------------------------* p80211ind_distribution** Called by the MSD to deliver a distribution system type * indication message.* * Arguments:* wlandev WLAN device struct* skb skb containing message to deliver** Returns: * nothing* * Call context:* Any----------------------------------------------------------------*/void p80211ind_distribution( wlandevice_t *wlandev, struct sk_buff *skb){ DBFENTER; if ( nl_indicate != NULL ) {/* skb = alloc_skb(len, GFP_ATOMIC); skb_put(skb, len); memcpy(skb->data, msg, len);*/ netlink_broadcast(nl_indicate, skb, 0, P80211_NL_MCAST_GRP_DIST, GFP_ATOMIC); } else { WLAN_LOG_DEBUG0(2,"Can't send indicate msg, no netlink i/f\n"); } DBFEXIT; return;}#endif /* CONFIG_NETLINK */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?