|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: *
27: *
28: */
29:
30: #include <IOKit/assert.h>
31: #include <IOKit/IOLib.h>
32: #include <IOKit/network/IONetworkController.h>
33: #include <IOKit/network/IONetworkInterface.h>
34: #include <IOKit/network/IONetworkUserClient.h>
35: #include <IOKit/network/IONetworkData.h>
36:
37: //------------------------------------------------------------------------
38:
39: #define super IOUserClient
40: OSDefineMetaClassAndStructors( IONetworkUserClient, IOUserClient )
41:
42: #ifdef DEBUG
43: #define DLOG(fmt, args...) IOLog(fmt, ## args)
44: #else
45: #define DLOG
46: #endif
47:
48: //---------------------------------------------------------------------------
49: // Factory method that performs allocation and initialization
50: // of an IONetworkUserClient instance.
51: //
52: // owningTask See IOUserClient.
53: //
54: // Returns an IONetworkUserClient on success, 0 otherwise.
55:
56: IONetworkUserClient * IONetworkUserClient::withTask(task_t owningTask)
57: {
58: IONetworkUserClient * me;
59:
60: me = new IONetworkUserClient;
61: if (me) {
62: if(!me->init()) {
63: me->release();
64: return 0;
65: }
66: me->_task = owningTask;
67: me->_notifyPort = MACH_PORT_NULL;
68: }
69: return me;
70: }
71:
72: //---------------------------------------------------------------------------
73: // Start the IONetworkUserClient.
74: // Open the provider, must be an IONetworkInterface object, and initialize
75: // the IOExternalMethod array.
76: //
77: // Returns true on success, false otherwise.
78:
79: bool IONetworkUserClient::start(IOService * provider)
80: {
81: UInt i;
82:
83: _owner = OSDynamicCast(IONetworkInterface, provider);
84: assert(_owner);
85:
86: _ctlr = OSDynamicCast(IONetworkController, _owner->getProvider());
87: if (!_ctlr)
88: return false;
89:
90: if (!super::start(_owner))
91: return false;
92:
93: if (!_owner->open(this))
94: return false;
95:
96: // Initialize the call structures.
97: //
98: i = kIONUCResetNetworkDataIndex;
99: _methods[i].object = this;
100: _methods[i].func = (IOMethod) &IONetworkUserClient::resetNetworkData;
101: _methods[i].count0 = kIONUCResetNetworkDataInputs;
102: _methods[i].count1 = kIONUCResetNetworkDataOutputs;
103: _methods[i].flags = kIONUCResetNetworkDataFlags;
104:
105: i = kIONUCWriteNetworkDataIndex;
106: _methods[i].object = this;
107: _methods[i].func = (IOMethod) &IONetworkUserClient::writeNetworkData;
108: _methods[i].count0 = kIONUCWriteNetworkDataInput0;
109: _methods[i].count1 = kIONUCWriteNetworkDataInput1;
110: _methods[i].flags = kIONUCWriteNetworkDataFlags;
111:
112: i = kIONUCReadNetworkDataIndex;
113: _methods[i].object = this;
114: _methods[i].func = (IOMethod) &IONetworkUserClient::readNetworkData;
115: _methods[i].count0 = kIONUCReadNetworkDataInputs;
116: _methods[i].count1 = kIONUCReadNetworkDataOutputs;
117: _methods[i].flags = kIONUCReadNetworkDataFlags;
118:
119: i = kIONUCGetNetworkDataCapacityIndex;
120: _methods[i].object = this;
121: _methods[i].func = (IOMethod)
122: &IONetworkUserClient::getNetworkDataCapacity;
123: _methods[i].count0 = kIONUCGetNetworkDataCapacityInputs;
124: _methods[i].count1 = kIONUCGetNetworkDataCapacityOutputs;
125: _methods[i].flags = kIONUCGetNetworkDataCapacityFlags;
126:
127: i = kIONUCGetNetworkDataHandleIndex;
128: _methods[i].object = this;
129: _methods[i].func = (IOMethod) &IONetworkUserClient::getNetworkDataHandle;
130: _methods[i].count0 = kIONUCGetNetworkDataHandleInputs;
131: _methods[i].count1 = kIONUCGetNetworkDataHandleOutputs;
132: _methods[i].flags = kIONUCGetNetworkDataHandleFlags;
133:
134: return true;
135: }
136:
137: //---------------------------------------------------------------------------
138: // Free the IONetworkUserClient instance.
139:
140: void IONetworkUserClient::free()
141: {
142: super::free();
143: }
144:
145: //---------------------------------------------------------------------------
146: // Handle a client close. Close and detach from our owner (provider).
147: //
148: // Return kIOReturnSuccess.
149:
150: IOReturn IONetworkUserClient::clientClose()
151: {
152: if (_owner) {
153: _owner->close(this);
154: detach(_owner);
155: }
156:
157: return kIOReturnSuccess;
158: }
159:
160: //---------------------------------------------------------------------------
161: // Handle client death. Close and detach from our owner (provider).
162: //
163: // Return kIOReturnSuccess.
164:
165: IOReturn IONetworkUserClient::clientDied()
166: {
167: return clientClose();
168: }
169:
170: //---------------------------------------------------------------------------
171: // Look up an entry from the method array. Called by IOUserClient to fetch
172: // the method entry, encoded by an IOExternalMethod structure, that correspond
173: // to the index given.
174: //
175: // index: The method index.
176: //
177: // Returns a pointer to a IOExternalMethod structure containing the
178: // method definition.
179:
180: IOExternalMethod *
181: IONetworkUserClient::getExternalMethodForIndex(UInt32 index)
182: {
183: if (index >= kIONUCLastIndex)
184: return 0;
185: else
186: return &_methods[index];
187: }
188:
189: //---------------------------------------------------------------------------
190: // Called by a client to register its notification port.
191: //
192: // port: A mach port where the notification message should be sent.
193: //
194: // type: The type of notification that the client is interested in.
195: //
196: // refCon: An argument to deliver with the notification.
197: //
198: // Returns kIOReturnUnsupported if the notification type is unknown,
199: // kIOReturnSuccess otherwise.
200:
201: IOReturn IONetworkUserClient::registerNotificationPort(mach_port_t port,
202: UInt32 type,
203: UInt32 refCon)
204: {
205: if (type != kIONUCNotificationTypeLinkChange)
206: return kIOReturnUnsupported;
207:
208: _notifyPort = port;
209:
210: return kIOReturnSuccess;
211: }
212:
213: //---------------------------------------------------------------------------
214: // Deliver a notification to the registered notification port.
215: //
216: // type: The type of notification being delivered.
217: //
218: // Returns kIOReturnSuccess on success,
219: // kIOReturnUnsupported if the notification type is unknown, or
220: // kIOReturnError for a mach messaging error.
221:
222: IOReturn IONetworkUserClient::deliverNotification(UInt32 type)
223: {
224: IOReturn ret = kIOReturnSuccess;
225:
226: IONetworkNotifyMsg msg = {
227: {
228: MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,0), /* mach_msg_bits_t msgh_bits */
229: sizeof(IONetworkNotifyMsg), /* mach_msg_size_t msgh_size */
230: MACH_PORT_NULL, /* mach_port_t msgh_remote_port */
231: MACH_PORT_NULL, /* mach_port_t msgh_local_port */
232: 0, /* mach_msg_size_t msgh_reserved */
233: type /* mach_msg_id_t msgh_id */
234: }};
235:
236: if (type != kIONUCNotificationTypeLinkChange)
237: return kIOReturnUnsupported;
238:
239: if (_notifyPort != MACH_PORT_NULL) {
240: msg.h.msgh_remote_port = _notifyPort;
241:
242: kern_return_t r = mach_msg_send_from_kernel(
243: (mach_msg_header_t *) &msg,
244: msg.h.msgh_size);
245:
246: if (r != MACH_MSG_SUCCESS) {
247: IOLog("%s: msg_send error: %x\n", getName(), (UInt) r);
248: ret = kIOReturnError;
249: }
250: }
251:
252: return ret;
253: }
254:
255: //---------------------------------------------------------------------------
256: // Fill the data buffer in an IONetworkData object with zeroes.
257: //
258: // key: The OSSymbol key of an IONetworkData object.
259: //
260: // Returns kIOReturnSuccess on success,
261: // kIOReturnBadArgument if an argument is invalid, or an
262: // error from IONetworkData::reset().
263:
264: IOReturn IONetworkUserClient::resetNetworkData(OSSymbol * key)
265: {
266: IONetworkData * data;
267: IOReturn ret;
268:
269: data = _owner->getNetworkData(key);
270: ret = data ? data->reset() : kIOReturnBadArgument;
271:
272: return ret;
273: }
274:
275: //---------------------------------------------------------------------------
276: // Write to the data buffer in an IONetworkData object from a buffer
277: // provided by the caller.
278: //
279: // key: The OSSymbol key of an IONetworkData object.
280: //
281: // srcBuf: The data to write is taken from this buffer.
282: //
283: // inSize: The size of the source buffer.
284: //
285: // Returns kIOReturnSuccess on success,
286: // kIOReturnBadArgument if an argument is invalid, or an
287: // error from IONetworkData::write().
288:
289: IOReturn
290: IONetworkUserClient::writeNetworkData(OSSymbol * key,
291: void * srcBuffer,
292: IOByteCount srcBufferSize)
293: {
294: IONetworkData * data;
295: IOReturn ret;
296:
297: if (!srcBuffer || (srcBufferSize == 0))
298: return kIOReturnBadArgument;
299:
300: data = _owner->getNetworkData(key);
301: ret = data ? data->write(srcBuffer, srcBufferSize) : kIOReturnBadArgument;
302:
303: return ret;
304: }
305:
306: //---------------------------------------------------------------------------
307: // Read (copy) the data buffer in an IONetworkData object to a buffer
308: // provided by the caller.
309: //
310: // key: The OSSymbol key of an IONetworkData object.
311: //
312: // destBuf: The buffer where the data shall be written to.
313: //
314: // inOutSizeP: Pointer to an integer that the caller must initialize
315: // to contain the size of the buffer. This method will overwrite
316: // it with the actual number of bytes written to the buffer.
317: //
318: // Returns kIOReturnSuccess on success,
319: // kIOReturnBadArgument if an argument is invalid, or an
320: // error from IONetworkData::read().
321:
322: IOReturn
323: IONetworkUserClient::readNetworkData(OSSymbol * key,
324: void * destBuf,
325: IOByteCount * inOutSizeP)
326: {
327: IONetworkData * data;
328: IOReturn ret ;
329:
330: if (!destBuf || !inOutSizeP)
331: return kIOReturnBadArgument;
332:
333: data = _owner->getNetworkData(key);
334: ret = data ? data->read(destBuf, (UInt *) inOutSizeP) :
335: kIOReturnBadArgument;
336:
337: return ret;
338: }
339:
340: //---------------------------------------------------------------------------
341: // Get the capacity of an IONetworkData object.
342: //
343: // key: The OSSymbol key associated with the IONetworkData object.
344: //
345: // capacityP: On success, the capacity is written to the integer
346: // at this address.
347: //
348: // Returns kIOReturnSuccess on success, or
349: // kIOReturnBadArgument if an argument is invalid.
350:
351: IOReturn
352: IONetworkUserClient::getNetworkDataCapacity(OSSymbol * key,
353: UInt32 * capacityP)
354: {
355: IOReturn ret = kIOReturnBadArgument;
356: IONetworkData * data;
357:
358: data = _owner->getNetworkData(key);
359:
360: if (data) {
361: *capacityP = data->getCapacity();
362: ret = kIOReturnSuccess;
363: }
364:
365: return ret;
366: }
367:
368: //---------------------------------------------------------------------------
369: // Called to obtain a handle that maps to an IONetworkData object.
370: // This handle can be later passed to other methods in this class
371: // to refer to the same object.
372: //
373: // name: A C string with the name of the IONetworkData object.
374: //
375: // handle: If an IONetworkData object with the given name is found,
376: // then its associated OSSymbol object is written to this address.
377: //
378: // nameSize: The size of the name string, including the final
379: // null character.
380: //
381: // handleSizeP: The size of the buffer allocated by the caller
382: // to store the handle. This should be 4 bytes.
383: //
384: // Returns kIOReturnSuccess on success,
385: // kIOReturnBadArgument if an argument is invalid, or
386: // kIOReturnNoMemory if unable to allocate memory.
387:
388: IOReturn
389: IONetworkUserClient::getNetworkDataHandle(char * name,
390: OSObject ** handle,
391: IOByteCount nameSize,
392: IOByteCount * handleSizeP)
393: {
394: IOReturn ret = kIOReturnBadArgument;
395: const OSSymbol * key;
396:
397: if (!name || !nameSize || (name[nameSize - 1] != '\0') ||
398: (*handleSizeP != sizeof(*handle)))
399: return kIOReturnBadArgument;
400:
401: key = OSSymbol::withCStringNoCopy(name);
402: if (!key)
403: return kIOReturnNoMemory;
404:
405: if (_owner->getNetworkData(key))
406: {
407: *handle = (OSObject *) key;
408: ret = kIOReturnSuccess;
409: }
410:
411: if (key)
412: key->release();
413:
414: return ret;
415: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.