You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
7.5 KiB
229 lines
7.5 KiB
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
* Copyright (C) 2016 Mopria Alliance, Inc.
|
|
* Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "lib_wprint.h"
|
|
#include "ippstatus_capabilities.h" // move these to above the calls to cups files
|
|
#include "ipphelper.h"
|
|
#include "cups.h"
|
|
#include "http-private.h"
|
|
#include "wprint_debug.h"
|
|
|
|
#define TAG "ippstatus_capabilities"
|
|
|
|
/*
|
|
* Requested printer attributes
|
|
*/
|
|
static const char *pattrs[] = {
|
|
"ipp-versions-supported",
|
|
"printer-make-and-model",
|
|
"printer-info",
|
|
"printer-dns-sd-name",
|
|
"printer-name",
|
|
"printer-location",
|
|
"printer-uuid",
|
|
"printer-uri-supported",
|
|
"uri-security-supported",
|
|
"uri-authentication-supported",
|
|
"color-supported",
|
|
"copies-supported",
|
|
"document-format-supported",
|
|
"media-col-default",
|
|
"media-default",
|
|
"media-left-margin-supported",
|
|
"media-right-margin-supported",
|
|
"media-top-margin-supported",
|
|
"media-bottom-margin-supported",
|
|
"media-supported",
|
|
"media-type-supported",
|
|
"output-bin-supported",
|
|
"print-color-mode-supported",
|
|
"print-quality-supported",
|
|
"printer-output-tray",
|
|
"printer-resolution-supported",
|
|
"sides-supported",
|
|
"printer-device-id",
|
|
"epcl-version-supported",
|
|
"pclm-raster-back-side",
|
|
"pclm-strip-height-preferred",
|
|
"pclm-compression-method-preferred",
|
|
"pclm-source-resolution-supported",
|
|
"pwg-raster-document-sheet-back",
|
|
"document-format-details-supported",
|
|
"media-ready",
|
|
"media-col-ready"
|
|
};
|
|
|
|
static void _init(const ifc_printer_capabilities_t *this_p,
|
|
const wprint_connect_info_t *info);
|
|
|
|
static status_t _get_capabilities(const ifc_printer_capabilities_t *this_p,
|
|
printer_capabilities_t *capabilities);
|
|
|
|
static void _destroy(const ifc_printer_capabilities_t *this_p);
|
|
|
|
static ifc_printer_capabilities_t _capabilities_ifc = {
|
|
.init = _init, .get_capabilities = _get_capabilities, .get_margins = NULL,
|
|
.destroy = _destroy,
|
|
};
|
|
|
|
typedef struct {
|
|
http_t *http;
|
|
printer_capabilities_t printer_caps;
|
|
ifc_printer_capabilities_t ifc;
|
|
} ipp_capabilities_t;
|
|
|
|
const ifc_printer_capabilities_t *ipp_status_get_capabilities_ifc(const ifc_wprint_t *wprint_ifc) {
|
|
LOGD("ipp_status_get_capabilities_ifc: Enter");
|
|
ipp_capabilities_t *caps = (ipp_capabilities_t *) malloc(sizeof(ipp_capabilities_t));
|
|
if (caps == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
memset(caps, 0, sizeof(ipp_capabilities_t));
|
|
caps->http = NULL;
|
|
|
|
memcpy(&caps->ifc, &_capabilities_ifc, sizeof(ifc_printer_capabilities_t));
|
|
return &caps->ifc;
|
|
}
|
|
|
|
static void _init(const ifc_printer_capabilities_t *this_p,
|
|
const wprint_connect_info_t *connect_info) {
|
|
LOGD("_init: Enter");
|
|
ipp_capabilities_t *caps;
|
|
do {
|
|
if (this_p == NULL) {
|
|
continue;
|
|
}
|
|
caps = IMPL(ipp_capabilities_t, ifc, this_p);
|
|
|
|
if (caps->http != NULL) {
|
|
LOGD("_init(): http != NULL closing HTTP");
|
|
httpClose(caps->http);
|
|
}
|
|
|
|
caps->http = ipp_cups_connect(connect_info, caps->printer_caps.printerUri,
|
|
sizeof(caps->printer_caps.printerUri));
|
|
getResourceFromURI(caps->printer_caps.printerUri, caps->printer_caps.httpResource, 1024);
|
|
if (caps->http == NULL) {
|
|
LOGE("_init(): http is NULL ");
|
|
}
|
|
} while (0);
|
|
}
|
|
|
|
static status_t _get_capabilities(const ifc_printer_capabilities_t *this_p,
|
|
printer_capabilities_t *capabilities) {
|
|
LOGD("_get_capabilities: Enter");
|
|
status_t result = ERROR;
|
|
ipp_capabilities_t *caps = NULL;
|
|
ipp_t *request = NULL; // IPP request object
|
|
ipp_t *response = NULL; // IPP response object
|
|
ipp_attribute_t *attrptr; // Attribute pointer
|
|
int op = IPP_GET_PRINTER_ATTRIBUTES;
|
|
|
|
ipp_status_t ipp_status; // Status of IPP request
|
|
|
|
if (capabilities != NULL) {
|
|
memset(capabilities, 0, sizeof(printer_capabilities_t));
|
|
}
|
|
|
|
do {
|
|
if (this_p == NULL) {
|
|
break;
|
|
}
|
|
|
|
caps = IMPL(ipp_capabilities_t, ifc, this_p);
|
|
if (caps->http == NULL) {
|
|
LOGD("_get_capabilities: caps->http is NULL");
|
|
break;
|
|
}
|
|
|
|
request = ippNewRequest(op);
|
|
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
|
|
caps->printer_caps.printerUri);
|
|
|
|
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes",
|
|
sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs);
|
|
|
|
LOGD("IPP_GET_PRINTER_ATTRIBUTES %s request:", ippOpString(op));
|
|
for (attrptr = ippFirstAttribute(request); attrptr; attrptr = ippNextAttribute(request)) {
|
|
print_attr(attrptr);
|
|
}
|
|
|
|
response = ipp_doCupsRequest(caps->http, request, caps->printer_caps.httpResource,
|
|
caps->printer_caps.printerUri);
|
|
if (response == NULL) {
|
|
ipp_status = cupsLastError();
|
|
LOGE("_get_capabilities: %s response is null: ipp_status %d %s",
|
|
caps->printer_caps.printerUri, ipp_status, ippErrorString(ipp_status));
|
|
} else {
|
|
ipp_status = cupsLastError();
|
|
LOGD("ipp CUPS last ERROR: %d, %s", ipp_status, ippErrorString(ipp_status));
|
|
LOGD("%s received, now call parse_printerAttributes:", ippOpString(op));
|
|
parse_printerAttributes(response, capabilities);
|
|
|
|
#if LOG_LEVEL <= LEVEL_DEBUG
|
|
for (attrptr = ippFirstAttribute(response); attrptr; attrptr = ippNextAttribute(
|
|
response)) {
|
|
print_attr(attrptr);
|
|
}
|
|
#endif // LOG_LEVEL <= LEVEL_DEBUG
|
|
if ((attrptr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) == NULL) {
|
|
LOGD("printer-state: null");
|
|
} else {
|
|
LOGI("printer-state %d", (ipp_pstate_t) ippGetInteger(attrptr, 0));
|
|
}
|
|
}
|
|
|
|
if (ipp_status >= IPP_OK && ipp_status < IPP_REDIRECTION_OTHER_SITE && response != NULL) {
|
|
result = OK;
|
|
} else {
|
|
result = ERROR;
|
|
}
|
|
} while (0);
|
|
|
|
ippDelete(response);
|
|
ippDelete(request);
|
|
|
|
if ((caps != NULL) && (capabilities != NULL)) {
|
|
memcpy(capabilities->httpResource, caps->printer_caps.httpResource,
|
|
sizeof(capabilities->httpResource));
|
|
}
|
|
|
|
LOGI(" ippstatus_capabilities: _get_capabilities: returning %d:", result);
|
|
return result;
|
|
}
|
|
|
|
static void _destroy(const ifc_printer_capabilities_t *this_p) {
|
|
ipp_capabilities_t *caps;
|
|
LOGD("_destroy(): enter");
|
|
do {
|
|
if (this_p == NULL) {
|
|
continue;
|
|
}
|
|
|
|
caps = IMPL(ipp_capabilities_t, ifc, this_p);
|
|
if (caps->http != NULL) {
|
|
httpClose(caps->http);
|
|
}
|
|
free(caps);
|
|
} while (0);
|
|
} |