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 "JoystickProtocolHandler.h" 18 #include "KeyboardProtocolHandler.h" 19 #include "MouseProtocolHandler.h" 20 #include "TabletProtocolHandler.h" 21 22 23 ProtocolHandler::ProtocolHandler(HIDDevice *device, const char *basePath, 24 size_t ringBufferSize) 25 : fStatus(B_NO_INIT), 26 fDevice(device), 27 fBasePath(basePath), 28 fPublishPath(NULL), 29 fRingBuffer(NULL), 30 fNextHandler(NULL) 31 { 32 if (ringBufferSize > 0) { 33 fRingBuffer = create_ring_buffer(ringBufferSize); 34 if (fRingBuffer == NULL) { 35 TRACE_ALWAYS("failed to create requested ring buffer\n"); 36 fStatus = B_NO_MEMORY; 37 return; 38 } 39 } 40 41 fStatus = B_OK; 42 } 43 44 45 ProtocolHandler::~ProtocolHandler() 46 { 47 if (fRingBuffer) { 48 delete_ring_buffer(fRingBuffer); 49 fRingBuffer = NULL; 50 } 51 52 free(fPublishPath); 53 } 54 55 56 void 57 ProtocolHandler::SetPublishPath(char *publishPath) 58 { 59 free(fPublishPath); 60 fPublishPath = publishPath; 61 } 62 63 64 void 65 ProtocolHandler::AddHandlers(HIDDevice &device, ProtocolHandler *&handlerList, 66 uint32 &handlerCount) 67 { 68 TRACE("adding protocol handlers\n"); 69 70 HIDParser &parser = device.Parser(); 71 HIDCollection *rootCollection = parser.RootCollection(); 72 if (rootCollection == NULL) 73 return; 74 75 uint32 appCollectionCount = rootCollection->CountChildrenFlat( 76 COLLECTION_APPLICATION); 77 TRACE("root collection holds %" B_PRIu32 " application collection%s\n", 78 appCollectionCount, appCollectionCount != 1 ? "s" : ""); 79 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 // NOTE: The driver publishes devices for all added handlers. 90 91 // TODO: How does this work if a device is not a compound device 92 // like a keyboard with built-in touchpad, but allows multiple 93 // alternative configurations like a tablet that works as either 94 // regular (relative) mouse, or (absolute) tablet? 95 KeyboardProtocolHandler::AddHandlers(device, *collection, handlerList); 96 JoystickProtocolHandler::AddHandlers(device, *collection, handlerList); 97 MouseProtocolHandler::AddHandlers(device, *collection, handlerList); 98 TabletProtocolHandler::AddHandlers(device, *collection, handlerList); 99 } 100 101 handlerCount = 0; 102 ProtocolHandler *handler = handlerList; 103 while (handler != NULL) { 104 handler = handler->NextHandler(); 105 handlerCount++; 106 } 107 108 if (handlerCount == 0) { 109 TRACE_ALWAYS("no handlers for hid device\n"); 110 return; 111 } 112 113 TRACE("added %" B_PRId32 " handlers for hid device\n", handlerCount); 114 } 115 116 117 status_t 118 ProtocolHandler::Open(uint32 flags, uint32 *cookie) 119 { 120 return fDevice->Open(this, flags); 121 } 122 123 124 status_t 125 ProtocolHandler::Close(uint32 *cookie) 126 { 127 *cookie |= PROTOCOL_HANDLER_COOKIE_FLAG_CLOSED; 128 // This lets the handlers know that this user is gone. 129 130 return fDevice->Close(this); 131 } 132 133 134 status_t 135 ProtocolHandler::Read(uint32 *cookie, off_t position, void *buffer, 136 size_t *numBytes) 137 { 138 TRACE_ALWAYS("unhandled read on protocol handler\n"); 139 *numBytes = 0; 140 return B_ERROR; 141 } 142 143 144 status_t 145 ProtocolHandler::Write(uint32 *cookie, off_t position, const void *buffer, 146 size_t *numBytes) 147 { 148 TRACE_ALWAYS("unhandled write on protocol handler\n"); 149 *numBytes = 0; 150 return B_ERROR; 151 } 152 153 154 status_t 155 ProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer, size_t length) 156 { 157 TRACE_ALWAYS("unhandled control on protocol handler\n"); 158 return B_ERROR; 159 } 160 161 162 int32 163 ProtocolHandler::RingBufferReadable() 164 { 165 return ring_buffer_readable(fRingBuffer); 166 } 167 168 169 status_t 170 ProtocolHandler::RingBufferRead(void *buffer, size_t length) 171 { 172 ring_buffer_user_read(fRingBuffer, (uint8 *)buffer, length); 173 return B_OK; 174 } 175 176 177 status_t 178 ProtocolHandler::RingBufferWrite(const void *buffer, size_t length) 179 { 180 ring_buffer_write(fRingBuffer, (const uint8 *)buffer, length); 181 return B_OK; 182 } 183 184 185 void 186 ProtocolHandler::SetNextHandler(ProtocolHandler *nextHandler) 187 { 188 fNextHandler = nextHandler; 189 } 190