• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2016 Mopria Alliance, Inc.
4  * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include "lib_wprint.h"
23 #include "ippstatus_capabilities.h"   // move these to above the calls to cups files
24 #include "ipphelper.h"
25 #include "cups.h"
26 #include "http-private.h"
27 #include "wprint_debug.h"
28 
29 #define TAG "ippstatus_capabilities"
30 
31 /*
32  * Requested printer attributes
33  */
34 static const char *pattrs[] = {
35         "ipp-versions-supported",
36         "printer-make-and-model",
37         "printer-name",
38         "printer-location",
39         "printer-uuid",
40         "printer-uri-supported",
41         "uri-security-supported",
42         "uri-authentication-supported",
43         "color-supported",
44         "copies-supported",
45         "document-format-supported",
46         "media-col-default",
47         "media-default",
48         "media-left-margin-supported",
49         "media-right-margin-supported",
50         "media-top-margin-supported",
51         "media-bottom-margin-supported",
52         "media-supported",
53         "media-type-supported",
54         "output-bin-supported",
55         "print-color-mode-supported",
56         "printer-resolution-supported",
57         "sides-supported",
58         "printer-device-id",
59         "epcl-version-supported",
60         "pclm-raster-back-side",
61         "pclm-strip-height-preferred",
62         "pclm-compression-method-preferred",
63         "pclm-source-resolution-supported",
64         "document-format-details-supported"
65 };
66 
67 static void _init(const ifc_printer_capabilities_t *this_p,
68         const wprint_connect_info_t *info);
69 
70 static status_t _get_capabilities(const ifc_printer_capabilities_t *this_p,
71         printer_capabilities_t *capabilities);
72 
73 static void _destroy(const ifc_printer_capabilities_t *this_p);
74 
75 static ifc_printer_capabilities_t _capabilities_ifc = {
76         .init = _init, .get_capabilities = _get_capabilities, .get_margins = NULL,
77         .destroy = _destroy,
78 };
79 
80 typedef struct {
81     http_t *http;
82     printer_capabilities_t printer_caps;
83     ifc_printer_capabilities_t ifc;
84 } ipp_capabilities_t;
85 
ipp_status_get_capabilities_ifc(const ifc_wprint_t * wprint_ifc)86 const ifc_printer_capabilities_t *ipp_status_get_capabilities_ifc(const ifc_wprint_t *wprint_ifc) {
87     LOGD("ipp_status_get_capabilities_ifc: Enter");
88     ipp_capabilities_t *caps = (ipp_capabilities_t *) malloc(sizeof(ipp_capabilities_t));
89     if (caps == NULL) {
90         return NULL;
91     }
92 
93     memset(caps, 0, sizeof(ipp_capabilities_t));
94     caps->http = NULL;
95 
96     memcpy(&caps->ifc, &_capabilities_ifc, sizeof(ifc_printer_capabilities_t));
97     return &caps->ifc;
98 }
99 
_init(const ifc_printer_capabilities_t * this_p,const wprint_connect_info_t * connect_info)100 static void _init(const ifc_printer_capabilities_t *this_p,
101         const wprint_connect_info_t *connect_info) {
102     LOGD("_init: Enter");
103     ipp_capabilities_t *caps;
104     do {
105         if (this_p == NULL) {
106             continue;
107         }
108         caps = IMPL(ipp_capabilities_t, ifc, this_p);
109 
110         if (caps->http != NULL) {
111             LOGD("_init(): http != NULL closing HTTP");
112             httpClose(caps->http);
113         }
114 
115         caps->http = ipp_cups_connect(connect_info, caps->printer_caps.printerUri,
116                 sizeof(caps->printer_caps.printerUri));
117         getResourceFromURI(caps->printer_caps.printerUri, caps->printer_caps.httpResource, 1024);
118         if (caps->http == NULL) {
119             LOGE("_init(): http is NULL ");
120         }
121     } while (0);
122 }
123 
_get_capabilities(const ifc_printer_capabilities_t * this_p,printer_capabilities_t * capabilities)124 static status_t _get_capabilities(const ifc_printer_capabilities_t *this_p,
125         printer_capabilities_t *capabilities) {
126     LOGD("_get_capabilities: Enter");
127     status_t result = ERROR;
128     ipp_capabilities_t *caps = NULL;
129     ipp_t *request = NULL; // IPP request object
130     ipp_t *response = NULL; // IPP response object
131     ipp_attribute_t *attrptr; // Attribute pointer
132     int op = IPP_GET_PRINTER_ATTRIBUTES;
133 
134     ipp_status_t ipp_status; // Status of IPP request
135 
136     if (capabilities != NULL) {
137         memset(capabilities, 0, sizeof(printer_capabilities_t));
138     }
139 
140     do {
141         if (this_p == NULL) {
142             break;
143         }
144 
145         caps = IMPL(ipp_capabilities_t, ifc, this_p);
146         if (caps->http == NULL) {
147             LOGD("_get_capabilities: caps->http is NULL");
148             break;
149         }
150 
151         request = ippNewRequest(op);
152 
153         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
154                 caps->printer_caps.printerUri);
155 
156         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes",
157                 sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs);
158 
159         LOGD("IPP_GET_PRINTER_ATTRIBUTES %s request:", ippOpString(op));
160         for (attrptr = ippFirstAttribute(request); attrptr; attrptr = ippNextAttribute(request)) {
161             print_attr(attrptr);
162         }
163 
164         response = ipp_doCupsRequest(caps->http, request, caps->printer_caps.httpResource,
165                 caps->printer_caps.printerUri);
166         if (response == NULL) {
167             ipp_status = cupsLastError();
168             LOGE("_get_capabilities: %s response is null:  ipp_status %d %s",
169                     caps->printer_caps.printerUri, ipp_status, ippErrorString(ipp_status));
170         } else {
171             ipp_status = cupsLastError();
172             LOGD("ipp CUPS last ERROR: %d, %s", ipp_status, ippErrorString(ipp_status));
173             LOGD("%s received, now call parse_printerAttributes:", ippOpString(op));
174             parse_printerAttributes(response, capabilities);
175 
176 #if LOG_LEVEL <= LEVEL_DEBUG
177             for (attrptr = ippFirstAttribute(response); attrptr; attrptr = ippNextAttribute(
178                     response)) {
179                 print_attr(attrptr);
180             }
181 #endif // LOG_LEVEL <= LEVEL_DEBUG
182             if ((attrptr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) == NULL) {
183                 LOGD("printer-state: null");
184             } else {
185                 LOGI("printer-state %d", (ipp_pstate_t) ippGetInteger(attrptr, 0));
186             }
187         }
188 
189         if (ipp_status >= IPP_OK && ipp_status < IPP_REDIRECTION_OTHER_SITE && response != NULL) {
190             result = OK;
191         } else {
192             result = ERROR;
193         }
194     } while (0);
195 
196     ippDelete(response);
197     ippDelete(request);
198 
199     if ((caps != NULL) && (capabilities != NULL)) {
200         memcpy(capabilities->httpResource, caps->printer_caps.httpResource,
201                 sizeof(capabilities->httpResource));
202     }
203 
204     LOGI(" ippstatus_capabilities: _get_capabilities: returning %d:", result);
205     return result;
206 }
207 
_destroy(const ifc_printer_capabilities_t * this_p)208 static void _destroy(const ifc_printer_capabilities_t *this_p) {
209     ipp_capabilities_t *caps;
210     LOGD("_destroy(): enter");
211     do {
212         if (this_p == NULL) {
213             continue;
214         }
215 
216         caps = IMPL(ipp_capabilities_t, ifc, this_p);
217         if (caps->http != NULL) {
218             httpClose(caps->http);
219         }
220         free(caps);
221     } while (0);
222 }