1/*
2 * @APPLE_LICENSE_HEADER_START@
3 *
4 * Copyright (c) 2008 Apple, Inc.  All Rights Reserved.
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef _IOHIDRESOURCE_USERCLIENT_H
25#define _IOHIDRESOURCE_USERCLIENT_H
26
27#include <IOKit/hid/IOHIDKeys.h>
28/*!
29    @enum IOHIDResourceUserClientType
30    @abstract List of support user client types
31    @description Current the only support type is kIOHIDResourceUserClientTypeDevice.  The hope is to expand this out to support other HID resources/
32    @constant kIOHIDResourceUserClientTypeDevice Type for creating an in kernel representation of a HID driver that resides in user space
33*/
34typedef enum {
35    kIOHIDResourceUserClientTypeDevice = 0
36} IOHIDResourceUserClientType;
37
38/*!
39    @enum IOHIDResourceDeviceUserClientExternalMethods
40    @abstract List of external methods to be called from user land
41    @constant kIOHIDResourceDeviceUserClientMethodCreate Creates a device using a passed serialized property dictionary.
42    @constant kIOHIDResourceDeviceUserClientMethodTerminate Closes the device and releases memory.
43    @constant kIOHIDResourceDeviceUserClientMethodHandleReport Sends a report.
44    @constant kIOHIDResourceDeviceUserClientMethodPostReportResult Posts a report requested via GetReport and SetReport
45    @constant kIOHIDResourceDeviceUserClientMethodCount
46*/
47typedef enum {
48    kIOHIDResourceDeviceUserClientMethodCreate,
49    kIOHIDResourceDeviceUserClientMethodTerminate,
50    kIOHIDResourceDeviceUserClientMethodHandleReport,
51    kIOHIDResourceDeviceUserClientMethodPostReportResponse,
52    kIOHIDResourceDeviceUserClientMethodCount
53} IOHIDResourceDeviceUserClientExternalMethods;
54
55/*!
56    @enum IOHIDResourceUserClientResponseIndex
57    @abstract reponse indexes for report response
58*/
59typedef enum {
60    kIOHIDResourceUserClientResponseIndexResult = 0,
61    kIOHIDResourceUserClientResponseIndexToken,
62    kIOHIDResourceUserClientResponseIndexCount
63} IOHIDResourceUserClientResponseIndex;
64
65typedef enum {
66    kIOHIDResourceReportDirectionIn,
67    kIOHIDResourceReportDirectionOut
68} IOHIDResourceReportDirection;
69/*!
70    @enum IOHIDResourceDataQueueHeader
71    @abstract Header used for sending requests to user process
72*/
73typedef struct {
74    IOHIDResourceReportDirection    direction;
75    IOHIDReportType                 type;
76    uint32_t                        reportID;
77    uint32_t                        length;
78    uint64_t                        token;
79} IOHIDResourceDataQueueHeader;
80
81/*
82 * Kernel
83 */
84#if KERNEL
85
86#include <IOKit/IOUserClient.h>
87#include <IOKit/IOSharedDataQueue.h>
88#include <IOKit/IOCommandGate.h>
89#include <IOKit/IOTimerEventSource.h>
90#include "IOHIDResource.h"
91#include "IOHIDUserDevice.h"
92
93
94/*! @class IOHIDResourceDeviceUserClient : public IOUserClient
95    @abstract
96*/
97/*! @class IOHIDResourceQueue : public IOSharedDataQueue
98    @abstract
99*/
100class IOHIDResourceQueue: public IOSharedDataQueue
101{
102    OSDeclareDefaultStructors( IOHIDResourceQueue )
103
104protected:
105    IOMemoryDescriptor *    _descriptor;
106
107public:
108    static IOHIDResourceQueue *withCapacity(UInt32 capacity);
109    virtual void free();
110
111    virtual Boolean enqueueReport(IOHIDResourceDataQueueHeader * header, IOMemoryDescriptor * report = NULL);
112
113    virtual IOMemoryDescriptor *getMemoryDescriptor();
114    virtual void setNotificationPort(mach_port_t port);
115};
116
117class IOHIDResourceDeviceUserClient : public IOUserClient
118{
119    OSDeclareDefaultStructors(IOHIDResourceDeviceUserClient);
120
121private:
122
123    IOHIDResource *         _owner;
124    OSDictionary *          _properties;
125    IOHIDUserDevice *       _device;
126    IOTimerEventSource *    _createDeviceTimer;
127    IOCommandGate *         _commandGate;
128    mach_port_t             _port;
129    IOHIDResourceQueue *    _queue;
130    OSSet *                 _pending;
131    uint32_t                _maxClientTimeoutUS;
132
133    static const IOExternalMethodDispatch _methods[kIOHIDResourceDeviceUserClientMethodCount];
134
135    static IOReturn _createDevice(IOHIDResourceDeviceUserClient *target, void *reference, IOExternalMethodArguments *arguments);
136    static IOReturn _terminateDevice(IOHIDResourceDeviceUserClient *target, void *reference, IOExternalMethodArguments *arguments);
137    static IOReturn _handleReport(IOHIDResourceDeviceUserClient *target,  void *reference, IOExternalMethodArguments *arguments);
138    static IOReturn _postReportResult(IOHIDResourceDeviceUserClient *target,  void *reference, IOExternalMethodArguments *arguments);
139
140
141    void createAndStartDeviceAsyncCallback();
142
143    typedef struct {
144        uint32_t                    selector;
145        IOExternalMethodArguments * arguments;
146        IOExternalMethodDispatch *  dispatch;
147        OSObject *                  target;
148        void *                      reference;
149    } ExternalMethodGatedArguments;
150
151    IOReturn externalMethodGated(ExternalMethodGatedArguments * arguments);
152    IOReturn registerNotificationPortGated(mach_port_t port);
153    IOReturn clientMemoryForTypeGated(IOOptionBits * options, IOMemoryDescriptor ** memory);
154
155    typedef struct {
156        IOMemoryDescriptor *        report;
157        IOHIDReportType             reportType;
158        IOOptionBits                options;
159    } ReportGatedArguments;
160
161    IOReturn getReportGated(ReportGatedArguments * arguments);
162    IOReturn setReportGated(ReportGatedArguments * arguments);
163
164    IOReturn createAndStartDevice();
165    IOReturn createAndStartDeviceAsync();
166    IOReturn createDevice(IOExternalMethodArguments *arguments);
167    IOReturn handleReport(IOExternalMethodArguments *arguments);
168    IOReturn postReportResult(IOExternalMethodArguments *arguments);
169    IOReturn terminateDevice();
170    void cleanupPendingReports();
171
172    IOMemoryDescriptor * createMemoryDescriptorFromInputArguments(IOExternalMethodArguments * arguments);
173
174    void ReportComplete(void *param, IOReturn res, UInt32 remaining);
175
176public:
177    /*! @function initWithTask
178        @abstract
179        @discussion
180    */
181    virtual bool initWithTask(task_t owningTask, void * security_id, UInt32 type);
182
183
184    /*! @function clientClose
185        @abstract
186        @discussion
187    */
188    virtual IOReturn clientClose(void);
189
190
191    /*! @function getService
192        @abstract
193        @discussion
194    */
195    virtual IOService * getService(void);
196
197
198    /*! @function externalMethod
199        @abstract
200        @discussion
201    */
202    virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments,
203                               IOExternalMethodDispatch *dispatch, OSObject *target,
204                               void *reference);
205
206    virtual IOReturn clientMemoryForType(UInt32 type, IOOptionBits * options, IOMemoryDescriptor ** memory );
207
208
209    /*! @function start
210        @abstract
211        @discussion
212    */
213    virtual bool start(IOService * provider);
214
215    virtual void stop(IOService * provider);
216
217    virtual void free();
218
219    virtual IOReturn registerNotificationPort(mach_port_t port, UInt32 type, io_user_reference_t refCon);
220
221    virtual IOReturn getReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options);
222
223    virtual IOReturn setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options);
224
225};
226
227
228#endif /* KERNEL */
229
230#endif /* _IOHIDRESOURCE_USERCLIENT_H */
231
232