NamedPipeObject * newNamedPipeObject (const char *name, NamedPipeInputCallback *callback, void *data) { NamedPipeObject *obj; if ((obj = malloc(sizeof(*obj)))) { memset(obj, 0, sizeof(*obj)); obj->callback = callback; obj->data = data; obj->createPipe = NULL; obj->monitorPipe = monitorInput; obj->resetPipe = NULL; obj->releaseResources = NULL; setNamedPipeMethods(obj); initializeHostPath(obj); initializeInputDescriptor(obj); initializeInputMonitor(obj); { const char *directory = getNamedPipeDirectory(); obj->host.path = directory? makePath(directory, name): NULL; } if (obj->host.path) { if (!obj->createPipe) { logUnsupportedOperation("create named pipe"); } else if (obj->createPipe(obj)) { if (!obj->monitorPipe) { logUnsupportedOperation("monitor named pipe"); } else if (obj->monitorPipe(obj)) { return obj; } closeInputDescriptor(obj); removePipe(obj); } deallocateHostPath(obj); } free(obj); } else { logMallocError(); } return NULL; }
int gioAwaitInput (GioEndpoint *endpoint, int timeout) { AwaitInputMethod *method = endpoint->methods->awaitInput; if (!method) return logUnsupportedOperation("awaitInput"); if (endpoint->input.to - endpoint->input.from) return 1; return method(&endpoint->handle, timeout); }
ssize_t gioWriteData (GioEndpoint *endpoint, const void *data, size_t size) { WriteDataMethod *method = endpoint->methods->writeData; if (!method) return logUnsupportedOperation("writeData"); return method(&endpoint->handle, data, size, endpoint->options.outputTimeout); }
ssize_t gioReadData (GioEndpoint *endpoint, void *buffer, size_t size, int wait) { ReadDataMethod *method = endpoint->methods->readData; if (!method) return logUnsupportedOperation("readData"); { unsigned char *start = buffer; unsigned char *next = start; while (size) { { unsigned int count = endpoint->input.to - endpoint->input.from; if (count) { if (count > size) count = size; memcpy(next, &endpoint->input.buffer[endpoint->input.from], count); endpoint->input.from += count; next += count; size -= count; continue; } endpoint->input.from = endpoint->input.to = 0; } if (endpoint->input.error) { if (next != start) break; errno = endpoint->input.error; endpoint->input.error = 0; return -1; } { ssize_t result = method(&endpoint->handle, &endpoint->input.buffer[endpoint->input.to], sizeof(endpoint->input.buffer) - endpoint->input.to, (wait? endpoint->options.inputTimeout: 0), 0); if (result > 0) { if (LOG_CATEGORY_FLAG(GENERIC_INPUT)) { logBytes(categoryLogLevel, "generic input", &endpoint->input.buffer[endpoint->input.to], result); } endpoint->input.to += result; wait = 1; } else { if (!result) break; if (errno == EAGAIN) break; endpoint->input.error = errno; } } } if (next == start) errno = EAGAIN; return next - start; } }
ssize_t gioGetHidFeature ( GioEndpoint *endpoint, unsigned char report, void *buffer, uint16_t size ) { GetHidFeatureMethod *method = endpoint->methods->getHidFeature; if (!method) return logUnsupportedOperation("getHidFeature"); return method(&endpoint->handle, report, buffer, size, endpoint->options.inputTimeout); }
ssize_t gioSetHidFeature ( GioEndpoint *endpoint, unsigned char report, const void *data, uint16_t size ) { SetHidFeatureMethod *method = endpoint->methods->setHidFeature; if (!method) return logUnsupportedOperation("setHidFeature"); return method(&endpoint->handle, report, data, size, endpoint->options.outputTimeout); }
size_t gioGetHidReportSize (GioEndpoint *endpoint, unsigned char report) { if (!endpoint->hidReportItems.address) { GetHidReportItemsMethod *method = endpoint->methods->getHidReportItems; if (!method) { logUnsupportedOperation("getHidReportItems"); return 0; } if (!method(&endpoint->handle, &endpoint->hidReportItems, endpoint->options.inputTimeout)) { return 0; } } { GetHidReportSizeMethod *method = endpoint->methods->getHidReportSize; if (!method) return logUnsupportedOperation("getHidReportSize"); return method(&endpoint->hidReportItems, report); } }
ssize_t gioAskResource ( GioEndpoint *endpoint, uint8_t recipient, uint8_t type, uint8_t request, uint16_t value, uint16_t index, void *buffer, uint16_t size ) { AskResourceMethod *method = endpoint->methods->askResource; if (!method) return logUnsupportedOperation("askResource"); return method(&endpoint->handle, recipient, type, request, value, index, buffer, size, endpoint->options.inputTimeout); }
ssize_t gioTellResource ( GioEndpoint *endpoint, uint8_t recipient, uint8_t type, uint8_t request, uint16_t value, uint16_t index, const void *data, uint16_t size ) { TellResourceMethod *method = endpoint->methods->tellResource; if (!method) return logUnsupportedOperation("tellResource"); return method(&endpoint->handle, recipient, type, request, value, index, data, size, endpoint->options.outputTimeout); }
int gioDisconnectResource (GioEndpoint *endpoint) { int ok = 0; DisconnectResourceMethod *method = endpoint->methods->disconnectResource; if (!method) { logUnsupportedOperation("disconnectResource"); } else if (method(&endpoint->handle)) { ok = 1; } if (endpoint->hidReportItems.address) free(endpoint->hidReportItems.address); free(endpoint); return ok; }
int gioReconfigureResource ( GioEndpoint *endpoint, const SerialParameters *parameters ) { int ok = 0; ReconfigureResourceMethod *method = endpoint->methods->reconfigureResource; if (!method) { logUnsupportedOperation("reconfigureResource"); } else if (method(&endpoint->handle, parameters)) { setBytesPerSecond(endpoint, parameters); ok = 1; } return ok; }