1/*
2 * Copyright 2009-2011, Michael Lotz, mmlr@mlotz.ch.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <stdlib.h>
8#include <ring_buffer.h>
9
10#include "Driver.h"
11#include "HIDCollection.h"
12#include "HIDDevice.h"
13#include "HIDReport.h"
14#include "ProtocolHandler.h"
15
16// includes for the different protocol handlers
17#include "KeyboardProtocolHandler.h"
18#include "MouseProtocolHandler.h"
19#include "JoystickProtocolHandler.h"
20
21
22ProtocolHandler::ProtocolHandler(HIDDevice *device, const char *basePath,
23	size_t ringBufferSize)
24	:	fStatus(B_NO_INIT),
25		fDevice(device),
26		fBasePath(basePath),
27		fPublishPath(NULL),
28		fRingBuffer(NULL),
29		fNextHandler(NULL)
30{
31	if (ringBufferSize > 0) {
32		fRingBuffer = create_ring_buffer(ringBufferSize);
33		if (fRingBuffer == NULL) {
34			TRACE_ALWAYS("failed to create requested ring buffer\n");
35			fStatus = B_NO_MEMORY;
36			return;
37		}
38	}
39
40	fStatus = B_OK;
41}
42
43
44ProtocolHandler::~ProtocolHandler()
45{
46	if (fRingBuffer) {
47		delete_ring_buffer(fRingBuffer);
48		fRingBuffer = NULL;
49	}
50
51	free(fPublishPath);
52}
53
54
55void
56ProtocolHandler::SetPublishPath(char *publishPath)
57{
58	free(fPublishPath);
59	fPublishPath = publishPath;
60}
61
62
63void
64ProtocolHandler::AddHandlers(HIDDevice &device, ProtocolHandler *&handlerList,
65	uint32 &handlerCount)
66{
67	TRACE("adding protocol handlers\n");
68
69	HIDParser &parser = device.Parser();
70	HIDCollection *rootCollection = parser.RootCollection();
71	if (rootCollection == NULL)
72		return;
73
74	uint32 appCollectionCount = rootCollection->CountChildrenFlat(
75		COLLECTION_APPLICATION);
76	TRACE("root collection holds %lu application collection%s\n",
77		appCollectionCount, appCollectionCount != 1 ? "s" : "");
78
79	handlerCount = 0;
80	for (uint32  i = 0; i < appCollectionCount; i++) {
81		HIDCollection *collection = rootCollection->ChildAtFlat(
82			COLLECTION_APPLICATION, i);
83		if (collection == NULL)
84			continue;
85
86		TRACE("collection usage page %u usage id %u\n",
87			collection->UsagePage(), collection->UsageID());
88
89		KeyboardProtocolHandler::AddHandlers(device, *collection, handlerList);
90		MouseProtocolHandler::AddHandlers(device, *collection, handlerList);
91		JoystickProtocolHandler::AddHandlers(device, *collection, handlerList);
92	}
93
94	ProtocolHandler *handler = handlerList;
95	while (handler != NULL) {
96		handler = handler->NextHandler();
97		handlerCount++;
98	}
99
100	if (handlerCount == 0) {
101		TRACE_ALWAYS("no handlers for hid device\n");
102		return;
103	}
104
105	TRACE("added %ld handlers for hid device\n", handlerCount);
106}
107
108
109status_t
110ProtocolHandler::Open(uint32 flags, uint32 *cookie)
111{
112	return fDevice->Open(this, flags);
113}
114
115
116status_t
117ProtocolHandler::Close(uint32 *cookie)
118{
119	return fDevice->Close(this);
120}
121
122
123status_t
124ProtocolHandler::Read(uint32 *cookie, off_t position, void *buffer,
125	size_t *numBytes)
126{
127	TRACE_ALWAYS("unhandled read on protocol handler\n");
128	*numBytes = 0;
129	return B_ERROR;
130}
131
132
133status_t
134ProtocolHandler::Write(uint32 *cookie, off_t position, const void *buffer,
135	size_t *numBytes)
136{
137	TRACE_ALWAYS("unhandled write on protocol handler\n");
138	*numBytes = 0;
139	return B_ERROR;
140}
141
142
143status_t
144ProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
145{
146	TRACE_ALWAYS("unhandled control on protocol handler\n");
147	return B_ERROR;
148}
149
150
151int32
152ProtocolHandler::RingBufferReadable()
153{
154	return ring_buffer_readable(fRingBuffer);
155}
156
157
158status_t
159ProtocolHandler::RingBufferRead(void *buffer, size_t length)
160{
161	ring_buffer_user_read(fRingBuffer, (uint8 *)buffer, length);
162	return B_OK;
163}
164
165
166status_t
167ProtocolHandler::RingBufferWrite(const void *buffer, size_t length)
168{
169	ring_buffer_write(fRingBuffer, (const uint8 *)buffer, length);
170	return B_OK;
171}
172
173
174void
175ProtocolHandler::SetNextHandler(ProtocolHandler *nextHandler)
176{
177	fNextHandler = nextHandler;
178}
179