1: /*
2:
3: File: WiFiUserClient.cpp
4: Program: GTDriver
5: Author: Michael Roßberg
6: mick@binaervarianz.de
7: Description: GTDriver is a free driver for PrismGT based cards under OS X.
8:
9: This file is part of GTDriver.
10:
11: GTDriver is free software; you can redistribute it and/or modify
12: it under the terms of the GNU General Public License as published by
13: the Free Software Foundation; either version 2 of the License, or
14: (at your option) any later version.
15:
16: GTDriver is distributed in the hope that it will be useful,
17: but WITHOUT ANY WARRANTY; without even the implied warranty of
18: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19: GNU General Public License for more details.
20:
21: You should have received a copy of the GNU General Public License
22: along with GTDriver; if not, write to the Free Software
23: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24: */
25:
26: #include "WiFiUserClient.h"
27: #include <IOKit/IOMessage.h>
28:
29: #define super IOUserClient
30: OSDefineMetaClassAndStructors(WiFiUserClient, IOUserClient);
31:
32: IODataQueue* WiFiUserClient::_packetQueue = NULL;
33:
34: bool WiFiUserClient::start(IOService* provider) {
35: WLEnter();
36:
37: if (!super::start(provider)) {
38: WLLogErr("super::start() failed");
39: return false;
40: }
41:
42: _provider = OSDynamicCast(WiFiController, provider);
43: if (!_provider) {
44: WLLogErr("_provider failed");
45: return false;
46: }
47:
48: _userCommandGate = IOCommandGate::commandGate(this);
49: if (!_userCommandGate) {
50: WLLogErr("Couldn't get CommandGate");
51: return false;
52: }
53:
54: IOWorkLoop* wl = _provider->getWorkLoop();
55: if (wl->addEventSource(_userCommandGate) != kIOReturnSuccess) {
56: WLLogErr("Couldn't add gate to workloop");
57: return false;
58: }
59: _packetQueue = _provider->getPacketQueue();
60: if (!_packetQueue) {
61: WLLogCrit("Could not obtain packetQueue");
62: return false;
63: }
64: return true;
65: }
66:
67: void WiFiUserClient::stop(IOService* provider) {
68: WLEnter();
69: }
70:
71: bool WiFiUserClient::initWithTask(task_t owningTask, void* securityToken, UInt32 type) {
72: WLEnter();
73:
74: if (!super::initWithTask(owningTask, securityToken, type))
75: return false;
76:
77: if (!owningTask)
78: return false;
79:
80: _owningTask = owningTask;
81: _securityToken = securityToken;
82: _securityType = type;
83: _provider = NULL;
84:
85: return true;
86: }
87:
88: IOReturn WiFiUserClient::clientClose(void) {
89: WLEnter();
90:
91: close();
92: terminate();
93:
94: if (_owningTask)
95: _owningTask = NULL;
96:
97: _provider = NULL;
98:
99: return kIOReturnSuccess;
100: }
101:
102: IOReturn WiFiUserClient::clientDied(void) {
103: WLEnter();
104:
105: return super::clientDied();
106: }
107:
108: IOReturn WiFiUserClient::message(UInt32 type, IOService * provider, void * argument) {
109: if (type == kIOMessageServiceIsTerminated) {
110: WLLogInfo("Provider did terminate!");
111: close();
112: terminate();
113: }
114: return super::message(type, provider, argument);
115: }
116:
117: IOExternalMethod* WiFiUserClient::
118: getTargetAndMethodForIndex(IOService** target, UInt32 index) {
119: static const IOExternalMethod sMethods[kWiFiUserClientLastMethod] = {
120: { // kWiFiUserClientOpen
121: NULL,
122: (IOMethod)&WiFiUserClient::open,
123: kIOUCScalarIScalarO,
124: 0,
125: 0
126: },
127: { // kWiFiUserClientClose
128: NULL,
129: (IOMethod)&WiFiUserClient::close,
130: kIOUCScalarIScalarO,
131: 0,
132: 0
133: },
134: {
135: // kWiFiUserClientGetLinkSpeed
136: NULL,
137: (IOMethod)&WiFiUserClient::_getLinkSpeed,
138: kIOUCScalarIScalarO,
139: 0,
140: 0
141: },
142: {
143: // kWiFiUserClientGetConnectionState
144: NULL,
145: (IOMethod)&WiFiUserClient::_getConnectionState,
146: kIOUCScalarIScalarO,
147: 0,
148: 0
149: },
150: {
151: // kWiFiUserClientGetFrequency
152: NULL,
153: (IOMethod)&WiFiUserClient::_getFrequency,
154: kIOUCScalarIScalarO,
155: 0,
156: 0
157: },
158: {
159: // kWiFiUserClientSetFrequency
160: NULL,
161: (IOMethod)&WiFiUserClient::_setFrequency,
162: kIOUCScalarIScalarO,
163: 1,
164: 0
165: },
166: {
167: // kWiFiUserClientSetSSID
168: NULL,
169: (IOMethod)&WiFiUserClient::_setSSID,
170: kIOUCScalarIStructI,
171: 0,
172: 0xFFFFFFFF
173: },
174: {
175: // kWiFiUserClientSetWEPKey
176: NULL,
177: (IOMethod)&WiFiUserClient::_setWEPKey,
178: kIOUCScalarIStructI,
179: 0,
180: 0xFFFFFFFF
181: },
182: {
183: // kWiFiUserClientGetScan
184: NULL,
185: (IOMethod)&WiFiUserClient::_getScan,
186: kIOUCScalarIStructO,
187: 0,
188: 0xFFFFFFFF
189: },
190: {
191: // kWiFiUserClientSetMode
192: NULL,
193: (IOMethod)&WiFiUserClient::_setMode,
194: kIOUCScalarIScalarO,
195: 1,
196: 0
197: },
198: };
199:
200: if (index < (UInt32)kWiFiUserClientLastMethod) {
201: *target = this;
202: return (IOExternalMethod*)&sMethods[index];
203: }
204:
205: return NULL;
206: }
207:
208: /*********************************************************************
209: *
210: *********************************************************************/
211:
212: IOReturn WiFiUserClient::open(void) {
213: WLEnter();
214:
215: if (isInactive())
216: return kIOReturnNotAttached;
217:
218: if (!_provider->open(this))
219: return kIOReturnExclusiveAccess;
220:
221: return kIOReturnSuccess;
222: }
223:
224: IOReturn WiFiUserClient::close(void) {
225: WLEnter();
226:
227: if (!_provider)
228: return kIOReturnNotAttached;
229:
230: if (_provider->isOpen(this)) {
231: _provider->close(this);
232: }
233:
234: return kIOReturnSuccess;
235: }
236:
237: #pragma mark -
238:
239: IOReturn WiFiUserClient::
240: clientMemoryForType(UInt32 type, IOOptionBits* optionBits,
241: IOMemoryDescriptor** memoryDescriptor) {
242: if (type == kWiFiUserClientMap) {
243: /* Set memoryDescriptor to DataQueue memory descriptor */
244:
245: if (!_packetQueue) {
246: WLLogCrit("NO PACKET QUEUE!");
247: return kIOReturnInternalError;
248: }
249:
250: *memoryDescriptor = _packetQueue->getMemoryDescriptor();
251: return (*memoryDescriptor != NULL) ? kIOReturnSuccess : kIOReturnInternalError;
252: }
253: else {
254: WLLogCrit("bad type");
255: return kIOReturnError;
256: }
257: }
258:
259: IOReturn WiFiUserClient::
260: registerNotificationPort(mach_port_t notificationPort,
261: UInt32 type, UInt32 refCon) {
262: if (type == kWiFiUserClientNotify) {
263: /* Set data queue's notification port */
264: if (!_packetQueue) {
265: WLLogCrit("NO PACKET QUEUE!");
266: return kIOReturnInternalError;
267: }
268:
269: _packetQueue->setNotificationPort(notificationPort);
270: return kIOReturnSuccess;
271: }
272: else {
273: WLLogCrit("bad type");
274: return kIOReturnError;
275: }
276: }
277:
278: #pragma mark -
279:
280: UInt32 WiFiUserClient::_getLinkSpeed() {
281: return _provider->getLinkSpeed();
282: }
283:
284: UInt32 WiFiUserClient::_getConnectionState() {
285: return _provider->getConnectionState();
286: }
287:
288: UInt32 WiFiUserClient::_getFrequency() {
289: return _provider->getFrequency() / 1000;
290: }
291:
292: IOReturn WiFiUserClient::_setSSID(const char *buffer, UInt32 size) {
293: return (_provider->setSSID(size, (UInt8*)buffer) ? kIOReturnSuccess : kIOReturnError);
294: }
295:
296: IOReturn WiFiUserClient::_setWEPKey(const char *buffer, UInt32 size) {
297: return (_provider->setKey(size, (UInt8*)buffer) ? kIOReturnSuccess : kIOReturnError);
298: }
299:
300: IOReturn WiFiUserClient::_getScan(const char *buffer, UInt32 size) {
301: UInt32 *s;
302: s = (UInt32*)buffer;
303: *s = size - 4;
304: return (_provider->getBSSNodesInRange(s, ((UInt8*)buffer) + 4) ? kIOReturnSuccess : kIOReturnError);
305: }
306:
307: IOReturn WiFiUserClient::_setFrequency(UInt32 frequency) {
308: return _provider->setFrequency(frequency * 1000);
309: }
310:
311: IOReturn WiFiUserClient::_setMode(UInt32 mode) {
312: return _provider->setMode((wirelessMode)mode);
313: }
314:
315: