1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * SNMP supplies functions for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2008-2015 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker *
6*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
7*5e7646d2SAndroid Build Coastguard Worker * information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers.
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "backend-private.h"
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/ppd-private.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/array.h>
17*5e7646d2SAndroid Build Coastguard Worker
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker /*
20*5e7646d2SAndroid Build Coastguard Worker * Local constants...
21*5e7646d2SAndroid Build Coastguard Worker */
22*5e7646d2SAndroid Build Coastguard Worker
23*5e7646d2SAndroid Build Coastguard Worker #define CUPS_MAX_SUPPLIES 32 /* Maximum number of supplies for a printer */
24*5e7646d2SAndroid Build Coastguard Worker #define CUPS_SUPPLY_TIMEOUT 2.0 /* Timeout for SNMP lookups */
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker #define CUPS_DEVELOPER_LOW 0x0001
27*5e7646d2SAndroid Build Coastguard Worker #define CUPS_DEVELOPER_EMPTY 0x0002
28*5e7646d2SAndroid Build Coastguard Worker #define CUPS_MARKER_SUPPLY_LOW 0x0004
29*5e7646d2SAndroid Build Coastguard Worker #define CUPS_MARKER_SUPPLY_EMPTY 0x0008
30*5e7646d2SAndroid Build Coastguard Worker #define CUPS_OPC_NEAR_EOL 0x0010
31*5e7646d2SAndroid Build Coastguard Worker #define CUPS_OPC_LIFE_OVER 0x0020
32*5e7646d2SAndroid Build Coastguard Worker #define CUPS_TONER_LOW 0x0040
33*5e7646d2SAndroid Build Coastguard Worker #define CUPS_TONER_EMPTY 0x0080
34*5e7646d2SAndroid Build Coastguard Worker #define CUPS_WASTE_ALMOST_FULL 0x0100
35*5e7646d2SAndroid Build Coastguard Worker #define CUPS_WASTE_FULL 0x0200
36*5e7646d2SAndroid Build Coastguard Worker #define CUPS_CLEANER_NEAR_EOL 0x0400 /* Proposed JPS3 */
37*5e7646d2SAndroid Build Coastguard Worker #define CUPS_CLEANER_LIFE_OVER 0x0800 /* Proposed JPS3 */
38*5e7646d2SAndroid Build Coastguard Worker
39*5e7646d2SAndroid Build Coastguard Worker #define CUPS_SNMP_NONE 0x0000
40*5e7646d2SAndroid Build Coastguard Worker #define CUPS_SNMP_CAPACITY 0x0001 /* Supply levels reported as percentages */
41*5e7646d2SAndroid Build Coastguard Worker
42*5e7646d2SAndroid Build Coastguard Worker
43*5e7646d2SAndroid Build Coastguard Worker /*
44*5e7646d2SAndroid Build Coastguard Worker * Local structures...
45*5e7646d2SAndroid Build Coastguard Worker */
46*5e7646d2SAndroid Build Coastguard Worker
47*5e7646d2SAndroid Build Coastguard Worker typedef struct /**** Printer supply data ****/
48*5e7646d2SAndroid Build Coastguard Worker {
49*5e7646d2SAndroid Build Coastguard Worker char name[CUPS_SNMP_MAX_STRING], /* Name of supply */
50*5e7646d2SAndroid Build Coastguard Worker color[8]; /* Color: "#RRGGBB" or "none" */
51*5e7646d2SAndroid Build Coastguard Worker int colorant, /* Colorant index */
52*5e7646d2SAndroid Build Coastguard Worker sclass, /* Supply class */
53*5e7646d2SAndroid Build Coastguard Worker type, /* Supply type */
54*5e7646d2SAndroid Build Coastguard Worker max_capacity, /* Maximum capacity */
55*5e7646d2SAndroid Build Coastguard Worker level; /* Current level value */
56*5e7646d2SAndroid Build Coastguard Worker } backend_supplies_t;
57*5e7646d2SAndroid Build Coastguard Worker
58*5e7646d2SAndroid Build Coastguard Worker typedef struct /**** Printer state table ****/
59*5e7646d2SAndroid Build Coastguard Worker {
60*5e7646d2SAndroid Build Coastguard Worker int bit; /* State bit */
61*5e7646d2SAndroid Build Coastguard Worker const char *keyword; /* IPP printer-state-reasons keyword */
62*5e7646d2SAndroid Build Coastguard Worker } backend_state_t;
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker
65*5e7646d2SAndroid Build Coastguard Worker /*
66*5e7646d2SAndroid Build Coastguard Worker * Local globals...
67*5e7646d2SAndroid Build Coastguard Worker */
68*5e7646d2SAndroid Build Coastguard Worker
69*5e7646d2SAndroid Build Coastguard Worker static http_addr_t current_addr; /* Current address */
70*5e7646d2SAndroid Build Coastguard Worker static int current_state = -1;
71*5e7646d2SAndroid Build Coastguard Worker /* Current device state bits */
72*5e7646d2SAndroid Build Coastguard Worker static int charset = -1; /* Character set for supply names */
73*5e7646d2SAndroid Build Coastguard Worker static unsigned quirks = CUPS_SNMP_NONE;
74*5e7646d2SAndroid Build Coastguard Worker /* Quirks we have to work around */
75*5e7646d2SAndroid Build Coastguard Worker static int num_supplies = 0;
76*5e7646d2SAndroid Build Coastguard Worker /* Number of supplies found */
77*5e7646d2SAndroid Build Coastguard Worker static backend_supplies_t supplies[CUPS_MAX_SUPPLIES];
78*5e7646d2SAndroid Build Coastguard Worker /* Supply information */
79*5e7646d2SAndroid Build Coastguard Worker static int supply_state = -1;
80*5e7646d2SAndroid Build Coastguard Worker /* Supply state info */
81*5e7646d2SAndroid Build Coastguard Worker
82*5e7646d2SAndroid Build Coastguard Worker static const int hrDeviceDescr[] =
83*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_hrDeviceDescr, 1, -1 };
84*5e7646d2SAndroid Build Coastguard Worker /* Device description OID */
85*5e7646d2SAndroid Build Coastguard Worker static const int hrPrinterStatus[] =
86*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_hrPrinterStatus, 1, -1 };
87*5e7646d2SAndroid Build Coastguard Worker /* Current state OID */
88*5e7646d2SAndroid Build Coastguard Worker static const int hrPrinterDetectedErrorState[] =
89*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_hrPrinterDetectedErrorState, 1, -1 };
90*5e7646d2SAndroid Build Coastguard Worker /* Current printer state bits OID */
91*5e7646d2SAndroid Build Coastguard Worker static const int prtGeneralCurrentLocalization[] =
92*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtGeneralCurrentLocalization, 1, -1 };
93*5e7646d2SAndroid Build Coastguard Worker static const int prtLocalizationCharacterSet[] =
94*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtLocalizationCharacterSet, 1, 1, -1 },
95*5e7646d2SAndroid Build Coastguard Worker prtLocalizationCharacterSetOffset =
96*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtLocalizationCharacterSet) /
97*5e7646d2SAndroid Build Coastguard Worker sizeof(prtLocalizationCharacterSet[0]));
98*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerColorantValue[] =
99*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerColorantValue, -1 },
100*5e7646d2SAndroid Build Coastguard Worker /* Colorant OID */
101*5e7646d2SAndroid Build Coastguard Worker prtMarkerColorantValueOffset =
102*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerColorantValue) /
103*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerColorantValue[0]));
104*5e7646d2SAndroid Build Coastguard Worker /* Offset to colorant index */
105*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerLifeCount[] =
106*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerLifeCount, 1, 1, -1 };
107*5e7646d2SAndroid Build Coastguard Worker /* Page counter OID */
108*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesEntry[] =
109*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesEntry, -1 };
110*5e7646d2SAndroid Build Coastguard Worker /* Supplies OID */
111*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesColorantIndex[] =
112*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesColorantIndex, -1 },
113*5e7646d2SAndroid Build Coastguard Worker /* Colorant index OID */
114*5e7646d2SAndroid Build Coastguard Worker prtMarkerSuppliesColorantIndexOffset =
115*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerSuppliesColorantIndex) /
116*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerSuppliesColorantIndex[0]));
117*5e7646d2SAndroid Build Coastguard Worker /* Offset to supply index */
118*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesDescription[] =
119*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesDescription, -1 },
120*5e7646d2SAndroid Build Coastguard Worker /* Description OID */
121*5e7646d2SAndroid Build Coastguard Worker prtMarkerSuppliesDescriptionOffset =
122*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerSuppliesDescription) /
123*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerSuppliesDescription[0]));
124*5e7646d2SAndroid Build Coastguard Worker /* Offset to supply index */
125*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesLevel[] =
126*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesLevel, -1 },
127*5e7646d2SAndroid Build Coastguard Worker /* Level OID */
128*5e7646d2SAndroid Build Coastguard Worker prtMarkerSuppliesLevelOffset =
129*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerSuppliesLevel) /
130*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerSuppliesLevel[0]));
131*5e7646d2SAndroid Build Coastguard Worker /* Offset to supply index */
132*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesMaxCapacity[] =
133*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesMaxCapacity, -1 },
134*5e7646d2SAndroid Build Coastguard Worker /* Max capacity OID */
135*5e7646d2SAndroid Build Coastguard Worker prtMarkerSuppliesMaxCapacityOffset =
136*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerSuppliesMaxCapacity) /
137*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerSuppliesMaxCapacity[0]));
138*5e7646d2SAndroid Build Coastguard Worker /* Offset to supply index */
139*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesClass[] =
140*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesClass, -1 },
141*5e7646d2SAndroid Build Coastguard Worker /* Class OID */
142*5e7646d2SAndroid Build Coastguard Worker prtMarkerSuppliesClassOffset =
143*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerSuppliesClass) /
144*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerSuppliesClass[0]));
145*5e7646d2SAndroid Build Coastguard Worker /* Offset to supply index */
146*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesType[] =
147*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesType, -1 },
148*5e7646d2SAndroid Build Coastguard Worker /* Type OID */
149*5e7646d2SAndroid Build Coastguard Worker prtMarkerSuppliesTypeOffset =
150*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerSuppliesType) /
151*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerSuppliesType[0]));
152*5e7646d2SAndroid Build Coastguard Worker /* Offset to supply index */
153*5e7646d2SAndroid Build Coastguard Worker static const int prtMarkerSuppliesSupplyUnit[] =
154*5e7646d2SAndroid Build Coastguard Worker { CUPS_OID_prtMarkerSuppliesSupplyUnit, -1 },
155*5e7646d2SAndroid Build Coastguard Worker /* Units OID */
156*5e7646d2SAndroid Build Coastguard Worker prtMarkerSuppliesSupplyUnitOffset =
157*5e7646d2SAndroid Build Coastguard Worker (sizeof(prtMarkerSuppliesSupplyUnit) /
158*5e7646d2SAndroid Build Coastguard Worker sizeof(prtMarkerSuppliesSupplyUnit[0]));
159*5e7646d2SAndroid Build Coastguard Worker /* Offset to supply index */
160*5e7646d2SAndroid Build Coastguard Worker
161*5e7646d2SAndroid Build Coastguard Worker static const backend_state_t printer_states[] =
162*5e7646d2SAndroid Build Coastguard Worker {
163*5e7646d2SAndroid Build Coastguard Worker /* { CUPS_TC_lowPaper, "media-low-report" }, */
164*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_noPaper | CUPS_TC_inputTrayEmpty, "media-empty-warning" },
165*5e7646d2SAndroid Build Coastguard Worker /* { CUPS_TC_lowToner, "toner-low-report" }, */ /* now use prtMarkerSupplies */
166*5e7646d2SAndroid Build Coastguard Worker /* { CUPS_TC_noToner, "toner-empty-warning" }, */ /* now use prtMarkerSupplies */
167*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_doorOpen, "door-open-report" },
168*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_jammed, "media-jam-warning" },
169*5e7646d2SAndroid Build Coastguard Worker /* { CUPS_TC_offline, "offline-report" }, */ /* unreliable */
170*5e7646d2SAndroid Build Coastguard Worker /* { CUPS_TC_serviceRequested | CUPS_TC_overduePreventMaint, "service-needed-warning" }, */ /* unreliable */
171*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_inputTrayMissing, "input-tray-missing-warning" },
172*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_outputTrayMissing, "output-tray-missing-warning" },
173*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_markerSupplyMissing, "marker-supply-missing-warning" },
174*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_outputNearFull, "output-area-almost-full-report" },
175*5e7646d2SAndroid Build Coastguard Worker { CUPS_TC_outputFull, "output-area-full-warning" }
176*5e7646d2SAndroid Build Coastguard Worker };
177*5e7646d2SAndroid Build Coastguard Worker
178*5e7646d2SAndroid Build Coastguard Worker static const backend_state_t supply_states[] =
179*5e7646d2SAndroid Build Coastguard Worker {
180*5e7646d2SAndroid Build Coastguard Worker { CUPS_DEVELOPER_LOW, "developer-low-report" },
181*5e7646d2SAndroid Build Coastguard Worker { CUPS_DEVELOPER_EMPTY, "developer-empty-warning" },
182*5e7646d2SAndroid Build Coastguard Worker { CUPS_MARKER_SUPPLY_LOW, "marker-supply-low-report" },
183*5e7646d2SAndroid Build Coastguard Worker { CUPS_MARKER_SUPPLY_EMPTY, "marker-supply-empty-warning" },
184*5e7646d2SAndroid Build Coastguard Worker { CUPS_OPC_NEAR_EOL, "opc-near-eol-report" },
185*5e7646d2SAndroid Build Coastguard Worker { CUPS_OPC_LIFE_OVER, "opc-life-over-warning" },
186*5e7646d2SAndroid Build Coastguard Worker { CUPS_TONER_LOW, "toner-low-report" },
187*5e7646d2SAndroid Build Coastguard Worker { CUPS_TONER_EMPTY, "toner-empty-warning" },
188*5e7646d2SAndroid Build Coastguard Worker { CUPS_WASTE_ALMOST_FULL, "waste-receptacle-almost-full-report" },
189*5e7646d2SAndroid Build Coastguard Worker { CUPS_WASTE_FULL, "waste-receptacle-full-warning" },
190*5e7646d2SAndroid Build Coastguard Worker { CUPS_CLEANER_NEAR_EOL, "cleaner-life-almost-over-report" },
191*5e7646d2SAndroid Build Coastguard Worker { CUPS_CLEANER_LIFE_OVER, "cleaner-life-over-warning" },
192*5e7646d2SAndroid Build Coastguard Worker };
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker
195*5e7646d2SAndroid Build Coastguard Worker /*
196*5e7646d2SAndroid Build Coastguard Worker * Local functions...
197*5e7646d2SAndroid Build Coastguard Worker */
198*5e7646d2SAndroid Build Coastguard Worker
199*5e7646d2SAndroid Build Coastguard Worker static void backend_init_supplies(int snmp_fd, http_addr_t *addr);
200*5e7646d2SAndroid Build Coastguard Worker static void backend_walk_cb(cups_snmp_t *packet, void *data);
201*5e7646d2SAndroid Build Coastguard Worker static void utf16_to_utf8(cups_utf8_t *dst, const unsigned char *src,
202*5e7646d2SAndroid Build Coastguard Worker size_t srcsize, size_t dstsize, int le);
203*5e7646d2SAndroid Build Coastguard Worker
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker /*
206*5e7646d2SAndroid Build Coastguard Worker * 'backendSNMPSupplies()' - Get the current supplies for a device.
207*5e7646d2SAndroid Build Coastguard Worker */
208*5e7646d2SAndroid Build Coastguard Worker
209*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on error */
backendSNMPSupplies(int snmp_fd,http_addr_t * addr,int * page_count,int * printer_state)210*5e7646d2SAndroid Build Coastguard Worker backendSNMPSupplies(
211*5e7646d2SAndroid Build Coastguard Worker int snmp_fd, /* I - SNMP socket */
212*5e7646d2SAndroid Build Coastguard Worker http_addr_t *addr, /* I - Printer address */
213*5e7646d2SAndroid Build Coastguard Worker int *page_count, /* O - Page count */
214*5e7646d2SAndroid Build Coastguard Worker int *printer_state) /* O - Printer state */
215*5e7646d2SAndroid Build Coastguard Worker {
216*5e7646d2SAndroid Build Coastguard Worker if (!httpAddrEqual(addr, ¤t_addr))
217*5e7646d2SAndroid Build Coastguard Worker backend_init_supplies(snmp_fd, addr);
218*5e7646d2SAndroid Build Coastguard Worker else if (num_supplies > 0)
219*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPWalk(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1,
220*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPDefaultCommunity(), prtMarkerSuppliesLevel,
221*5e7646d2SAndroid Build Coastguard Worker CUPS_SUPPLY_TIMEOUT, backend_walk_cb, NULL);
222*5e7646d2SAndroid Build Coastguard Worker
223*5e7646d2SAndroid Build Coastguard Worker if (page_count)
224*5e7646d2SAndroid Build Coastguard Worker *page_count = -1;
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker if (printer_state)
227*5e7646d2SAndroid Build Coastguard Worker *printer_state = -1;
228*5e7646d2SAndroid Build Coastguard Worker
229*5e7646d2SAndroid Build Coastguard Worker if (num_supplies > 0)
230*5e7646d2SAndroid Build Coastguard Worker {
231*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
232*5e7646d2SAndroid Build Coastguard Worker percent, /* Percent full */
233*5e7646d2SAndroid Build Coastguard Worker new_state, /* New state value */
234*5e7646d2SAndroid Build Coastguard Worker change_state, /* State change */
235*5e7646d2SAndroid Build Coastguard Worker new_supply_state = 0; /* Supply state */
236*5e7646d2SAndroid Build Coastguard Worker char value[CUPS_MAX_SUPPLIES * 4],
237*5e7646d2SAndroid Build Coastguard Worker /* marker-levels value string */
238*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into value string */
239*5e7646d2SAndroid Build Coastguard Worker cups_snmp_t packet; /* SNMP response packet */
240*5e7646d2SAndroid Build Coastguard Worker
241*5e7646d2SAndroid Build Coastguard Worker /*
242*5e7646d2SAndroid Build Coastguard Worker * Generate the marker-levels value string...
243*5e7646d2SAndroid Build Coastguard Worker */
244*5e7646d2SAndroid Build Coastguard Worker
245*5e7646d2SAndroid Build Coastguard Worker for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr))
246*5e7646d2SAndroid Build Coastguard Worker {
247*5e7646d2SAndroid Build Coastguard Worker if (supplies[i].max_capacity > 0 && supplies[i].level >= 0)
248*5e7646d2SAndroid Build Coastguard Worker percent = 100 * supplies[i].level / supplies[i].max_capacity;
249*5e7646d2SAndroid Build Coastguard Worker else if (supplies[i].level >= 0 && supplies[i].level <= 100 &&
250*5e7646d2SAndroid Build Coastguard Worker (quirks & CUPS_SNMP_CAPACITY))
251*5e7646d2SAndroid Build Coastguard Worker percent = supplies[i].level;
252*5e7646d2SAndroid Build Coastguard Worker else
253*5e7646d2SAndroid Build Coastguard Worker percent = 50;
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker if (supplies[i].sclass == CUPS_TC_receptacleThatIsFilled)
256*5e7646d2SAndroid Build Coastguard Worker percent = 100 - percent;
257*5e7646d2SAndroid Build Coastguard Worker
258*5e7646d2SAndroid Build Coastguard Worker if (percent <= 5)
259*5e7646d2SAndroid Build Coastguard Worker {
260*5e7646d2SAndroid Build Coastguard Worker switch (supplies[i].type)
261*5e7646d2SAndroid Build Coastguard Worker {
262*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_toner :
263*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_tonerCartridge :
264*5e7646d2SAndroid Build Coastguard Worker if (percent <= 1)
265*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_TONER_EMPTY;
266*5e7646d2SAndroid Build Coastguard Worker else
267*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_TONER_LOW;
268*5e7646d2SAndroid Build Coastguard Worker break;
269*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_ink :
270*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_inkCartridge :
271*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_inkRibbon :
272*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_solidWax :
273*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_ribbonWax :
274*5e7646d2SAndroid Build Coastguard Worker if (percent <= 1)
275*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_MARKER_SUPPLY_EMPTY;
276*5e7646d2SAndroid Build Coastguard Worker else
277*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_MARKER_SUPPLY_LOW;
278*5e7646d2SAndroid Build Coastguard Worker break;
279*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_developer :
280*5e7646d2SAndroid Build Coastguard Worker if (percent <= 1)
281*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_DEVELOPER_EMPTY;
282*5e7646d2SAndroid Build Coastguard Worker else
283*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_DEVELOPER_LOW;
284*5e7646d2SAndroid Build Coastguard Worker break;
285*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_coronaWire :
286*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_fuser :
287*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_opc :
288*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_transferUnit :
289*5e7646d2SAndroid Build Coastguard Worker if (percent <= 1)
290*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_OPC_LIFE_OVER;
291*5e7646d2SAndroid Build Coastguard Worker else
292*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_OPC_NEAR_EOL;
293*5e7646d2SAndroid Build Coastguard Worker break;
294*5e7646d2SAndroid Build Coastguard Worker #if 0 /* Because no two vendors report waste containers the same, disable SNMP reporting of same */
295*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_wasteInk :
296*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_wastePaper :
297*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_wasteToner :
298*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_wasteWater :
299*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_wasteWax :
300*5e7646d2SAndroid Build Coastguard Worker if (percent <= 1)
301*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_WASTE_FULL;
302*5e7646d2SAndroid Build Coastguard Worker else
303*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_WASTE_ALMOST_FULL;
304*5e7646d2SAndroid Build Coastguard Worker break;
305*5e7646d2SAndroid Build Coastguard Worker #endif /* 0 */
306*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_cleanerUnit :
307*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_fuserCleaningPad :
308*5e7646d2SAndroid Build Coastguard Worker if (percent <= 1)
309*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_CLEANER_LIFE_OVER;
310*5e7646d2SAndroid Build Coastguard Worker else
311*5e7646d2SAndroid Build Coastguard Worker new_supply_state |= CUPS_CLEANER_NEAR_EOL;
312*5e7646d2SAndroid Build Coastguard Worker break;
313*5e7646d2SAndroid Build Coastguard Worker }
314*5e7646d2SAndroid Build Coastguard Worker }
315*5e7646d2SAndroid Build Coastguard Worker
316*5e7646d2SAndroid Build Coastguard Worker if (i)
317*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ',';
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker if ((supplies[i].max_capacity > 0 || (quirks & CUPS_SNMP_CAPACITY)) &&
320*5e7646d2SAndroid Build Coastguard Worker supplies[i].level >= 0)
321*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(value) - (size_t)(ptr - value), "%d", percent);
322*5e7646d2SAndroid Build Coastguard Worker else
323*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, "-1", sizeof(value) - (size_t)(ptr - value));
324*5e7646d2SAndroid Build Coastguard Worker }
325*5e7646d2SAndroid Build Coastguard Worker
326*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ATTR: marker-levels=%s\n", value);
327*5e7646d2SAndroid Build Coastguard Worker
328*5e7646d2SAndroid Build Coastguard Worker if (supply_state < 0)
329*5e7646d2SAndroid Build Coastguard Worker change_state = 0xffff;
330*5e7646d2SAndroid Build Coastguard Worker else
331*5e7646d2SAndroid Build Coastguard Worker change_state = supply_state ^ new_supply_state;
332*5e7646d2SAndroid Build Coastguard Worker
333*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: new_supply_state=%x, change_state=%x\n",
334*5e7646d2SAndroid Build Coastguard Worker new_supply_state, change_state);
335*5e7646d2SAndroid Build Coastguard Worker
336*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
337*5e7646d2SAndroid Build Coastguard Worker i < (int)(sizeof(supply_states) / sizeof(supply_states[0]));
338*5e7646d2SAndroid Build Coastguard Worker i ++)
339*5e7646d2SAndroid Build Coastguard Worker if (change_state & supply_states[i].bit)
340*5e7646d2SAndroid Build Coastguard Worker {
341*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "STATE: %c%s\n",
342*5e7646d2SAndroid Build Coastguard Worker (new_supply_state & supply_states[i].bit) ? '+' : '-',
343*5e7646d2SAndroid Build Coastguard Worker supply_states[i].keyword);
344*5e7646d2SAndroid Build Coastguard Worker }
345*5e7646d2SAndroid Build Coastguard Worker
346*5e7646d2SAndroid Build Coastguard Worker supply_state = new_supply_state;
347*5e7646d2SAndroid Build Coastguard Worker
348*5e7646d2SAndroid Build Coastguard Worker /*
349*5e7646d2SAndroid Build Coastguard Worker * Get the current printer status bits...
350*5e7646d2SAndroid Build Coastguard Worker */
351*5e7646d2SAndroid Build Coastguard Worker
352*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
353*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
354*5e7646d2SAndroid Build Coastguard Worker hrPrinterDetectedErrorState))
355*5e7646d2SAndroid Build Coastguard Worker return (-1);
356*5e7646d2SAndroid Build Coastguard Worker
357*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
358*5e7646d2SAndroid Build Coastguard Worker packet.object_type != CUPS_ASN1_OCTET_STRING)
359*5e7646d2SAndroid Build Coastguard Worker return (-1);
360*5e7646d2SAndroid Build Coastguard Worker
361*5e7646d2SAndroid Build Coastguard Worker if (packet.object_value.string.num_bytes == 2)
362*5e7646d2SAndroid Build Coastguard Worker new_state = (packet.object_value.string.bytes[0] << 8) |
363*5e7646d2SAndroid Build Coastguard Worker packet.object_value.string.bytes[1];
364*5e7646d2SAndroid Build Coastguard Worker else if (packet.object_value.string.num_bytes == 1)
365*5e7646d2SAndroid Build Coastguard Worker new_state = (packet.object_value.string.bytes[0] << 8);
366*5e7646d2SAndroid Build Coastguard Worker else
367*5e7646d2SAndroid Build Coastguard Worker new_state = 0;
368*5e7646d2SAndroid Build Coastguard Worker
369*5e7646d2SAndroid Build Coastguard Worker if (current_state < 0)
370*5e7646d2SAndroid Build Coastguard Worker change_state = 0xffff;
371*5e7646d2SAndroid Build Coastguard Worker else
372*5e7646d2SAndroid Build Coastguard Worker change_state = current_state ^ new_state;
373*5e7646d2SAndroid Build Coastguard Worker
374*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: new_state=%x, change_state=%x\n", new_state,
375*5e7646d2SAndroid Build Coastguard Worker change_state);
376*5e7646d2SAndroid Build Coastguard Worker
377*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
378*5e7646d2SAndroid Build Coastguard Worker i < (int)(sizeof(printer_states) / sizeof(printer_states[0]));
379*5e7646d2SAndroid Build Coastguard Worker i ++)
380*5e7646d2SAndroid Build Coastguard Worker if (change_state & printer_states[i].bit)
381*5e7646d2SAndroid Build Coastguard Worker {
382*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "STATE: %c%s\n",
383*5e7646d2SAndroid Build Coastguard Worker (new_state & printer_states[i].bit) ? '+' : '-',
384*5e7646d2SAndroid Build Coastguard Worker printer_states[i].keyword);
385*5e7646d2SAndroid Build Coastguard Worker }
386*5e7646d2SAndroid Build Coastguard Worker
387*5e7646d2SAndroid Build Coastguard Worker current_state = new_state;
388*5e7646d2SAndroid Build Coastguard Worker
389*5e7646d2SAndroid Build Coastguard Worker /*
390*5e7646d2SAndroid Build Coastguard Worker * Get the current printer state...
391*5e7646d2SAndroid Build Coastguard Worker */
392*5e7646d2SAndroid Build Coastguard Worker
393*5e7646d2SAndroid Build Coastguard Worker if (printer_state)
394*5e7646d2SAndroid Build Coastguard Worker {
395*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
396*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
397*5e7646d2SAndroid Build Coastguard Worker hrPrinterStatus))
398*5e7646d2SAndroid Build Coastguard Worker return (-1);
399*5e7646d2SAndroid Build Coastguard Worker
400*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
401*5e7646d2SAndroid Build Coastguard Worker packet.object_type != CUPS_ASN1_INTEGER)
402*5e7646d2SAndroid Build Coastguard Worker return (-1);
403*5e7646d2SAndroid Build Coastguard Worker
404*5e7646d2SAndroid Build Coastguard Worker *printer_state = packet.object_value.integer;
405*5e7646d2SAndroid Build Coastguard Worker }
406*5e7646d2SAndroid Build Coastguard Worker
407*5e7646d2SAndroid Build Coastguard Worker /*
408*5e7646d2SAndroid Build Coastguard Worker * Get the current page count...
409*5e7646d2SAndroid Build Coastguard Worker */
410*5e7646d2SAndroid Build Coastguard Worker
411*5e7646d2SAndroid Build Coastguard Worker if (page_count)
412*5e7646d2SAndroid Build Coastguard Worker {
413*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
414*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
415*5e7646d2SAndroid Build Coastguard Worker prtMarkerLifeCount))
416*5e7646d2SAndroid Build Coastguard Worker return (-1);
417*5e7646d2SAndroid Build Coastguard Worker
418*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
419*5e7646d2SAndroid Build Coastguard Worker packet.object_type != CUPS_ASN1_COUNTER)
420*5e7646d2SAndroid Build Coastguard Worker return (-1);
421*5e7646d2SAndroid Build Coastguard Worker
422*5e7646d2SAndroid Build Coastguard Worker *page_count = packet.object_value.counter;
423*5e7646d2SAndroid Build Coastguard Worker }
424*5e7646d2SAndroid Build Coastguard Worker
425*5e7646d2SAndroid Build Coastguard Worker return (0);
426*5e7646d2SAndroid Build Coastguard Worker }
427*5e7646d2SAndroid Build Coastguard Worker else
428*5e7646d2SAndroid Build Coastguard Worker return (-1);
429*5e7646d2SAndroid Build Coastguard Worker }
430*5e7646d2SAndroid Build Coastguard Worker
431*5e7646d2SAndroid Build Coastguard Worker
432*5e7646d2SAndroid Build Coastguard Worker /*
433*5e7646d2SAndroid Build Coastguard Worker * 'backend_init_supplies()' - Initialize the supplies list.
434*5e7646d2SAndroid Build Coastguard Worker */
435*5e7646d2SAndroid Build Coastguard Worker
436*5e7646d2SAndroid Build Coastguard Worker static void
backend_init_supplies(int snmp_fd,http_addr_t * addr)437*5e7646d2SAndroid Build Coastguard Worker backend_init_supplies(
438*5e7646d2SAndroid Build Coastguard Worker int snmp_fd, /* I - SNMP socket */
439*5e7646d2SAndroid Build Coastguard Worker http_addr_t *addr) /* I - Printer address */
440*5e7646d2SAndroid Build Coastguard Worker {
441*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
442*5e7646d2SAndroid Build Coastguard Worker type; /* Current marker type */
443*5e7646d2SAndroid Build Coastguard Worker const char *community; /* SNMP community name */
444*5e7646d2SAndroid Build Coastguard Worker cups_file_t *cachefile; /* Cache file */
445*5e7646d2SAndroid Build Coastguard Worker const char *cachedir; /* CUPS_CACHEDIR value */
446*5e7646d2SAndroid Build Coastguard Worker char addrstr[1024], /* Address string */
447*5e7646d2SAndroid Build Coastguard Worker cachefilename[1024], /* Cache filename */
448*5e7646d2SAndroid Build Coastguard Worker description[CUPS_SNMP_MAX_STRING],
449*5e7646d2SAndroid Build Coastguard Worker /* Device description string */
450*5e7646d2SAndroid Build Coastguard Worker value[CUPS_MAX_SUPPLIES * (CUPS_SNMP_MAX_STRING * 4 + 3)],
451*5e7646d2SAndroid Build Coastguard Worker /* Value string */
452*5e7646d2SAndroid Build Coastguard Worker *ptr, /* Pointer into value string */
453*5e7646d2SAndroid Build Coastguard Worker *name_ptr; /* Pointer into name string */
454*5e7646d2SAndroid Build Coastguard Worker cups_snmp_t packet; /* SNMP response packet */
455*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd; /* PPD file for this queue */
456*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *ppdattr; /* cupsSNMPSupplies attribute */
457*5e7646d2SAndroid Build Coastguard Worker static const char * const types[] = /* Supply types */
458*5e7646d2SAndroid Build Coastguard Worker {
459*5e7646d2SAndroid Build Coastguard Worker "other",
460*5e7646d2SAndroid Build Coastguard Worker "unknown",
461*5e7646d2SAndroid Build Coastguard Worker "toner",
462*5e7646d2SAndroid Build Coastguard Worker "waste-toner",
463*5e7646d2SAndroid Build Coastguard Worker "ink",
464*5e7646d2SAndroid Build Coastguard Worker "ink-cartridge",
465*5e7646d2SAndroid Build Coastguard Worker "ink-ribbon",
466*5e7646d2SAndroid Build Coastguard Worker "waste-ink",
467*5e7646d2SAndroid Build Coastguard Worker "opc",
468*5e7646d2SAndroid Build Coastguard Worker "developer",
469*5e7646d2SAndroid Build Coastguard Worker "fuser-oil",
470*5e7646d2SAndroid Build Coastguard Worker "solid-wax",
471*5e7646d2SAndroid Build Coastguard Worker "ribbon-wax",
472*5e7646d2SAndroid Build Coastguard Worker "waste-wax",
473*5e7646d2SAndroid Build Coastguard Worker "fuser",
474*5e7646d2SAndroid Build Coastguard Worker "corona-wire",
475*5e7646d2SAndroid Build Coastguard Worker "fuser-oil-wick",
476*5e7646d2SAndroid Build Coastguard Worker "cleaner-unit",
477*5e7646d2SAndroid Build Coastguard Worker "fuser-cleaning-pad",
478*5e7646d2SAndroid Build Coastguard Worker "transfer-unit",
479*5e7646d2SAndroid Build Coastguard Worker "toner-cartridge",
480*5e7646d2SAndroid Build Coastguard Worker "fuser-oiler",
481*5e7646d2SAndroid Build Coastguard Worker "water",
482*5e7646d2SAndroid Build Coastguard Worker "waste-water",
483*5e7646d2SAndroid Build Coastguard Worker "glue-water-additive",
484*5e7646d2SAndroid Build Coastguard Worker "waste-paper",
485*5e7646d2SAndroid Build Coastguard Worker "binding-supply",
486*5e7646d2SAndroid Build Coastguard Worker "banding-supply",
487*5e7646d2SAndroid Build Coastguard Worker "stitching-wire",
488*5e7646d2SAndroid Build Coastguard Worker "shrink-wrap",
489*5e7646d2SAndroid Build Coastguard Worker "paper-wrap",
490*5e7646d2SAndroid Build Coastguard Worker "staples",
491*5e7646d2SAndroid Build Coastguard Worker "inserts",
492*5e7646d2SAndroid Build Coastguard Worker "covers"
493*5e7646d2SAndroid Build Coastguard Worker };
494*5e7646d2SAndroid Build Coastguard Worker
495*5e7646d2SAndroid Build Coastguard Worker
496*5e7646d2SAndroid Build Coastguard Worker /*
497*5e7646d2SAndroid Build Coastguard Worker * Reset state information...
498*5e7646d2SAndroid Build Coastguard Worker */
499*5e7646d2SAndroid Build Coastguard Worker
500*5e7646d2SAndroid Build Coastguard Worker current_addr = *addr;
501*5e7646d2SAndroid Build Coastguard Worker current_state = -1;
502*5e7646d2SAndroid Build Coastguard Worker num_supplies = -1;
503*5e7646d2SAndroid Build Coastguard Worker charset = -1;
504*5e7646d2SAndroid Build Coastguard Worker
505*5e7646d2SAndroid Build Coastguard Worker memset(supplies, 0, sizeof(supplies));
506*5e7646d2SAndroid Build Coastguard Worker
507*5e7646d2SAndroid Build Coastguard Worker /*
508*5e7646d2SAndroid Build Coastguard Worker * See if we should be getting supply levels via SNMP...
509*5e7646d2SAndroid Build Coastguard Worker */
510*5e7646d2SAndroid Build Coastguard Worker
511*5e7646d2SAndroid Build Coastguard Worker community = _cupsSNMPDefaultCommunity();
512*5e7646d2SAndroid Build Coastguard Worker if (!*community)
513*5e7646d2SAndroid Build Coastguard Worker return;
514*5e7646d2SAndroid Build Coastguard Worker
515*5e7646d2SAndroid Build Coastguard Worker if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL ||
516*5e7646d2SAndroid Build Coastguard Worker ((ppdattr = ppdFindAttr(ppd, "cupsSNMPSupplies", NULL)) != NULL &&
517*5e7646d2SAndroid Build Coastguard Worker ppdattr->value && _cups_strcasecmp(ppdattr->value, "true")))
518*5e7646d2SAndroid Build Coastguard Worker {
519*5e7646d2SAndroid Build Coastguard Worker ppdClose(ppd);
520*5e7646d2SAndroid Build Coastguard Worker return;
521*5e7646d2SAndroid Build Coastguard Worker }
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker if ((ppdattr = ppdFindAttr(ppd, "cupsSNMPQuirks", NULL)) != NULL)
524*5e7646d2SAndroid Build Coastguard Worker {
525*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(ppdattr->value, "capacity"))
526*5e7646d2SAndroid Build Coastguard Worker quirks |= CUPS_SNMP_CAPACITY;
527*5e7646d2SAndroid Build Coastguard Worker }
528*5e7646d2SAndroid Build Coastguard Worker
529*5e7646d2SAndroid Build Coastguard Worker ppdClose(ppd);
530*5e7646d2SAndroid Build Coastguard Worker
531*5e7646d2SAndroid Build Coastguard Worker /*
532*5e7646d2SAndroid Build Coastguard Worker * Get the device description...
533*5e7646d2SAndroid Build Coastguard Worker */
534*5e7646d2SAndroid Build Coastguard Worker
535*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
536*5e7646d2SAndroid Build Coastguard Worker community, CUPS_ASN1_GET_REQUEST, 1,
537*5e7646d2SAndroid Build Coastguard Worker hrDeviceDescr))
538*5e7646d2SAndroid Build Coastguard Worker return;
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
541*5e7646d2SAndroid Build Coastguard Worker packet.object_type != CUPS_ASN1_OCTET_STRING)
542*5e7646d2SAndroid Build Coastguard Worker {
543*5e7646d2SAndroid Build Coastguard Worker strlcpy(description, "Unknown", sizeof(description));
544*5e7646d2SAndroid Build Coastguard Worker num_supplies = 0;
545*5e7646d2SAndroid Build Coastguard Worker }
546*5e7646d2SAndroid Build Coastguard Worker else
547*5e7646d2SAndroid Build Coastguard Worker strlcpy(description, (char *)packet.object_value.string.bytes,
548*5e7646d2SAndroid Build Coastguard Worker sizeof(description));
549*5e7646d2SAndroid Build Coastguard Worker
550*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: hrDeviceDesc=\"%s\"\n", description);
551*5e7646d2SAndroid Build Coastguard Worker
552*5e7646d2SAndroid Build Coastguard Worker /*
553*5e7646d2SAndroid Build Coastguard Worker * See if we have already queried this device...
554*5e7646d2SAndroid Build Coastguard Worker */
555*5e7646d2SAndroid Build Coastguard Worker
556*5e7646d2SAndroid Build Coastguard Worker httpAddrString(addr, addrstr, sizeof(addrstr));
557*5e7646d2SAndroid Build Coastguard Worker
558*5e7646d2SAndroid Build Coastguard Worker if ((cachedir = getenv("CUPS_CACHEDIR")) == NULL)
559*5e7646d2SAndroid Build Coastguard Worker cachedir = CUPS_CACHEDIR;
560*5e7646d2SAndroid Build Coastguard Worker
561*5e7646d2SAndroid Build Coastguard Worker snprintf(cachefilename, sizeof(cachefilename), "%s/%s.snmp", cachedir,
562*5e7646d2SAndroid Build Coastguard Worker addrstr);
563*5e7646d2SAndroid Build Coastguard Worker
564*5e7646d2SAndroid Build Coastguard Worker if ((cachefile = cupsFileOpen(cachefilename, "r")) != NULL)
565*5e7646d2SAndroid Build Coastguard Worker {
566*5e7646d2SAndroid Build Coastguard Worker /*
567*5e7646d2SAndroid Build Coastguard Worker * Yes, read the cache file:
568*5e7646d2SAndroid Build Coastguard Worker *
569*5e7646d2SAndroid Build Coastguard Worker * 3 num_supplies charset
570*5e7646d2SAndroid Build Coastguard Worker * device description
571*5e7646d2SAndroid Build Coastguard Worker * supply structures...
572*5e7646d2SAndroid Build Coastguard Worker */
573*5e7646d2SAndroid Build Coastguard Worker
574*5e7646d2SAndroid Build Coastguard Worker if (cupsFileGets(cachefile, value, sizeof(value)))
575*5e7646d2SAndroid Build Coastguard Worker {
576*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "3 %d%d", &num_supplies, &charset) == 2 &&
577*5e7646d2SAndroid Build Coastguard Worker num_supplies <= CUPS_MAX_SUPPLIES &&
578*5e7646d2SAndroid Build Coastguard Worker cupsFileGets(cachefile, value, sizeof(value)))
579*5e7646d2SAndroid Build Coastguard Worker {
580*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(description, value))
581*5e7646d2SAndroid Build Coastguard Worker cupsFileRead(cachefile, (char *)supplies,
582*5e7646d2SAndroid Build Coastguard Worker (size_t)num_supplies * sizeof(backend_supplies_t));
583*5e7646d2SAndroid Build Coastguard Worker else
584*5e7646d2SAndroid Build Coastguard Worker {
585*5e7646d2SAndroid Build Coastguard Worker num_supplies = -1;
586*5e7646d2SAndroid Build Coastguard Worker charset = -1;
587*5e7646d2SAndroid Build Coastguard Worker }
588*5e7646d2SAndroid Build Coastguard Worker }
589*5e7646d2SAndroid Build Coastguard Worker else
590*5e7646d2SAndroid Build Coastguard Worker {
591*5e7646d2SAndroid Build Coastguard Worker num_supplies = -1;
592*5e7646d2SAndroid Build Coastguard Worker charset = -1;
593*5e7646d2SAndroid Build Coastguard Worker }
594*5e7646d2SAndroid Build Coastguard Worker }
595*5e7646d2SAndroid Build Coastguard Worker
596*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(cachefile);
597*5e7646d2SAndroid Build Coastguard Worker }
598*5e7646d2SAndroid Build Coastguard Worker
599*5e7646d2SAndroid Build Coastguard Worker /*
600*5e7646d2SAndroid Build Coastguard Worker * If the cache information isn't correct, scan for supplies...
601*5e7646d2SAndroid Build Coastguard Worker */
602*5e7646d2SAndroid Build Coastguard Worker
603*5e7646d2SAndroid Build Coastguard Worker if (charset < 0)
604*5e7646d2SAndroid Build Coastguard Worker {
605*5e7646d2SAndroid Build Coastguard Worker /*
606*5e7646d2SAndroid Build Coastguard Worker * Get the configured character set...
607*5e7646d2SAndroid Build Coastguard Worker */
608*5e7646d2SAndroid Build Coastguard Worker
609*5e7646d2SAndroid Build Coastguard Worker int oid[CUPS_SNMP_MAX_OID]; /* OID for character set */
610*5e7646d2SAndroid Build Coastguard Worker
611*5e7646d2SAndroid Build Coastguard Worker
612*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPWrite(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1,
613*5e7646d2SAndroid Build Coastguard Worker community, CUPS_ASN1_GET_REQUEST, 1,
614*5e7646d2SAndroid Build Coastguard Worker prtGeneralCurrentLocalization))
615*5e7646d2SAndroid Build Coastguard Worker return;
616*5e7646d2SAndroid Build Coastguard Worker
617*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
618*5e7646d2SAndroid Build Coastguard Worker packet.object_type != CUPS_ASN1_INTEGER)
619*5e7646d2SAndroid Build Coastguard Worker {
620*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr,
621*5e7646d2SAndroid Build Coastguard Worker "DEBUG: prtGeneralCurrentLocalization type is %x, expected %x!\n",
622*5e7646d2SAndroid Build Coastguard Worker packet.object_type, CUPS_ASN1_INTEGER);
623*5e7646d2SAndroid Build Coastguard Worker return;
624*5e7646d2SAndroid Build Coastguard Worker }
625*5e7646d2SAndroid Build Coastguard Worker
626*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtGeneralCurrentLocalization=%d\n",
627*5e7646d2SAndroid Build Coastguard Worker packet.object_value.integer);
628*5e7646d2SAndroid Build Coastguard Worker
629*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPCopyOID(oid, prtLocalizationCharacterSet, CUPS_SNMP_MAX_OID);
630*5e7646d2SAndroid Build Coastguard Worker oid[prtLocalizationCharacterSetOffset - 2] = packet.object_value.integer;
631*5e7646d2SAndroid Build Coastguard Worker
632*5e7646d2SAndroid Build Coastguard Worker
633*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPWrite(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1,
634*5e7646d2SAndroid Build Coastguard Worker community, CUPS_ASN1_GET_REQUEST, 1,
635*5e7646d2SAndroid Build Coastguard Worker oid))
636*5e7646d2SAndroid Build Coastguard Worker return;
637*5e7646d2SAndroid Build Coastguard Worker
638*5e7646d2SAndroid Build Coastguard Worker if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
639*5e7646d2SAndroid Build Coastguard Worker packet.object_type != CUPS_ASN1_INTEGER)
640*5e7646d2SAndroid Build Coastguard Worker {
641*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr,
642*5e7646d2SAndroid Build Coastguard Worker "DEBUG: prtLocalizationCharacterSet type is %x, expected %x!\n",
643*5e7646d2SAndroid Build Coastguard Worker packet.object_type, CUPS_ASN1_INTEGER);
644*5e7646d2SAndroid Build Coastguard Worker return;
645*5e7646d2SAndroid Build Coastguard Worker }
646*5e7646d2SAndroid Build Coastguard Worker
647*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtLocalizationCharacterSet=%d\n",
648*5e7646d2SAndroid Build Coastguard Worker packet.object_value.integer);
649*5e7646d2SAndroid Build Coastguard Worker charset = packet.object_value.integer;
650*5e7646d2SAndroid Build Coastguard Worker }
651*5e7646d2SAndroid Build Coastguard Worker
652*5e7646d2SAndroid Build Coastguard Worker if (num_supplies < 0)
653*5e7646d2SAndroid Build Coastguard Worker {
654*5e7646d2SAndroid Build Coastguard Worker /*
655*5e7646d2SAndroid Build Coastguard Worker * Walk the printer configuration information...
656*5e7646d2SAndroid Build Coastguard Worker */
657*5e7646d2SAndroid Build Coastguard Worker
658*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPWalk(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1,
659*5e7646d2SAndroid Build Coastguard Worker community, prtMarkerSuppliesEntry,
660*5e7646d2SAndroid Build Coastguard Worker CUPS_SUPPLY_TIMEOUT, backend_walk_cb, NULL);
661*5e7646d2SAndroid Build Coastguard Worker }
662*5e7646d2SAndroid Build Coastguard Worker
663*5e7646d2SAndroid Build Coastguard Worker /*
664*5e7646d2SAndroid Build Coastguard Worker * Save the cached information...
665*5e7646d2SAndroid Build Coastguard Worker */
666*5e7646d2SAndroid Build Coastguard Worker
667*5e7646d2SAndroid Build Coastguard Worker if (num_supplies < 0)
668*5e7646d2SAndroid Build Coastguard Worker num_supplies = 0;
669*5e7646d2SAndroid Build Coastguard Worker
670*5e7646d2SAndroid Build Coastguard Worker if ((cachefile = cupsFileOpen(cachefilename, "w")) != NULL)
671*5e7646d2SAndroid Build Coastguard Worker {
672*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cachefile, "3 %d %d\n", num_supplies, charset);
673*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cachefile, "%s\n", description);
674*5e7646d2SAndroid Build Coastguard Worker
675*5e7646d2SAndroid Build Coastguard Worker if (num_supplies > 0)
676*5e7646d2SAndroid Build Coastguard Worker cupsFileWrite(cachefile, (char *)supplies,
677*5e7646d2SAndroid Build Coastguard Worker (size_t)num_supplies * sizeof(backend_supplies_t));
678*5e7646d2SAndroid Build Coastguard Worker
679*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(cachefile);
680*5e7646d2SAndroid Build Coastguard Worker }
681*5e7646d2SAndroid Build Coastguard Worker
682*5e7646d2SAndroid Build Coastguard Worker if (num_supplies <= 0)
683*5e7646d2SAndroid Build Coastguard Worker return;
684*5e7646d2SAndroid Build Coastguard Worker
685*5e7646d2SAndroid Build Coastguard Worker /*
686*5e7646d2SAndroid Build Coastguard Worker * Get the colors...
687*5e7646d2SAndroid Build Coastguard Worker */
688*5e7646d2SAndroid Build Coastguard Worker
689*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_supplies; i ++)
690*5e7646d2SAndroid Build Coastguard Worker strlcpy(supplies[i].color, "none", sizeof(supplies[i].color));
691*5e7646d2SAndroid Build Coastguard Worker
692*5e7646d2SAndroid Build Coastguard Worker _cupsSNMPWalk(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1,
693*5e7646d2SAndroid Build Coastguard Worker community, prtMarkerColorantValue,
694*5e7646d2SAndroid Build Coastguard Worker CUPS_SUPPLY_TIMEOUT, backend_walk_cb, NULL);
695*5e7646d2SAndroid Build Coastguard Worker
696*5e7646d2SAndroid Build Coastguard Worker /*
697*5e7646d2SAndroid Build Coastguard Worker * Output the marker-colors attribute...
698*5e7646d2SAndroid Build Coastguard Worker */
699*5e7646d2SAndroid Build Coastguard Worker
700*5e7646d2SAndroid Build Coastguard Worker for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr))
701*5e7646d2SAndroid Build Coastguard Worker {
702*5e7646d2SAndroid Build Coastguard Worker if (i)
703*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ',';
704*5e7646d2SAndroid Build Coastguard Worker
705*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, supplies[i].color, sizeof(value) - (size_t)(ptr - value));
706*5e7646d2SAndroid Build Coastguard Worker }
707*5e7646d2SAndroid Build Coastguard Worker
708*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ATTR: marker-colors=%s\n", value);
709*5e7646d2SAndroid Build Coastguard Worker
710*5e7646d2SAndroid Build Coastguard Worker /*
711*5e7646d2SAndroid Build Coastguard Worker * Output the marker-names attribute (the double quoting is necessary to deal
712*5e7646d2SAndroid Build Coastguard Worker * with embedded quotes and commas in the marker names...)
713*5e7646d2SAndroid Build Coastguard Worker */
714*5e7646d2SAndroid Build Coastguard Worker
715*5e7646d2SAndroid Build Coastguard Worker for (i = 0, ptr = value; i < num_supplies; i ++)
716*5e7646d2SAndroid Build Coastguard Worker {
717*5e7646d2SAndroid Build Coastguard Worker if (i)
718*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ',';
719*5e7646d2SAndroid Build Coastguard Worker
720*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\'';
721*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\"';
722*5e7646d2SAndroid Build Coastguard Worker for (name_ptr = supplies[i].name; *name_ptr;)
723*5e7646d2SAndroid Build Coastguard Worker {
724*5e7646d2SAndroid Build Coastguard Worker if (*name_ptr == '\\' || *name_ptr == '\"' || *name_ptr == '\'')
725*5e7646d2SAndroid Build Coastguard Worker {
726*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\\';
727*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\\';
728*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\\';
729*5e7646d2SAndroid Build Coastguard Worker }
730*5e7646d2SAndroid Build Coastguard Worker
731*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *name_ptr++;
732*5e7646d2SAndroid Build Coastguard Worker }
733*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\"';
734*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\'';
735*5e7646d2SAndroid Build Coastguard Worker }
736*5e7646d2SAndroid Build Coastguard Worker
737*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
738*5e7646d2SAndroid Build Coastguard Worker
739*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ATTR: marker-names=%s\n", value);
740*5e7646d2SAndroid Build Coastguard Worker
741*5e7646d2SAndroid Build Coastguard Worker /*
742*5e7646d2SAndroid Build Coastguard Worker * Output the marker-types attribute...
743*5e7646d2SAndroid Build Coastguard Worker */
744*5e7646d2SAndroid Build Coastguard Worker
745*5e7646d2SAndroid Build Coastguard Worker for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr))
746*5e7646d2SAndroid Build Coastguard Worker {
747*5e7646d2SAndroid Build Coastguard Worker if (i)
748*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ',';
749*5e7646d2SAndroid Build Coastguard Worker
750*5e7646d2SAndroid Build Coastguard Worker type = supplies[i].type;
751*5e7646d2SAndroid Build Coastguard Worker
752*5e7646d2SAndroid Build Coastguard Worker if (type < CUPS_TC_other || type > CUPS_TC_covers)
753*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, "unknown", sizeof(value) - (size_t)(ptr - value));
754*5e7646d2SAndroid Build Coastguard Worker else
755*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, types[type - CUPS_TC_other], sizeof(value) - (size_t)(ptr - value));
756*5e7646d2SAndroid Build Coastguard Worker }
757*5e7646d2SAndroid Build Coastguard Worker
758*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ATTR: marker-types=%s\n", value);
759*5e7646d2SAndroid Build Coastguard Worker }
760*5e7646d2SAndroid Build Coastguard Worker
761*5e7646d2SAndroid Build Coastguard Worker
762*5e7646d2SAndroid Build Coastguard Worker /*
763*5e7646d2SAndroid Build Coastguard Worker * 'backend_walk_cb()' - Interpret the supply value responses.
764*5e7646d2SAndroid Build Coastguard Worker */
765*5e7646d2SAndroid Build Coastguard Worker
766*5e7646d2SAndroid Build Coastguard Worker static void
backend_walk_cb(cups_snmp_t * packet,void * data)767*5e7646d2SAndroid Build Coastguard Worker backend_walk_cb(cups_snmp_t *packet, /* I - SNMP packet */
768*5e7646d2SAndroid Build Coastguard Worker void *data) /* I - User data (unused) */
769*5e7646d2SAndroid Build Coastguard Worker {
770*5e7646d2SAndroid Build Coastguard Worker int i, j, k; /* Looping vars */
771*5e7646d2SAndroid Build Coastguard Worker static const char * const colors[][2] =
772*5e7646d2SAndroid Build Coastguard Worker { /* Standard color names */
773*5e7646d2SAndroid Build Coastguard Worker { "black", "#000000" },
774*5e7646d2SAndroid Build Coastguard Worker { "blue", "#0000FF" },
775*5e7646d2SAndroid Build Coastguard Worker { "brown", "#A52A2A" },
776*5e7646d2SAndroid Build Coastguard Worker { "cyan", "#00FFFF" },
777*5e7646d2SAndroid Build Coastguard Worker { "dark-gray", "#404040" },
778*5e7646d2SAndroid Build Coastguard Worker { "dark gray", "#404040" },
779*5e7646d2SAndroid Build Coastguard Worker { "dark-yellow", "#FFCC00" },
780*5e7646d2SAndroid Build Coastguard Worker { "dark yellow", "#FFCC00" },
781*5e7646d2SAndroid Build Coastguard Worker { "gold", "#FFD700" },
782*5e7646d2SAndroid Build Coastguard Worker { "gray", "#808080" },
783*5e7646d2SAndroid Build Coastguard Worker { "green", "#00FF00" },
784*5e7646d2SAndroid Build Coastguard Worker { "light-black", "#606060" },
785*5e7646d2SAndroid Build Coastguard Worker { "light black", "#606060" },
786*5e7646d2SAndroid Build Coastguard Worker { "light-cyan", "#E0FFFF" },
787*5e7646d2SAndroid Build Coastguard Worker { "light cyan", "#E0FFFF" },
788*5e7646d2SAndroid Build Coastguard Worker { "light-gray", "#D3D3D3" },
789*5e7646d2SAndroid Build Coastguard Worker { "light gray", "#D3D3D3" },
790*5e7646d2SAndroid Build Coastguard Worker { "light-magenta", "#FF77FF" },
791*5e7646d2SAndroid Build Coastguard Worker { "light magenta", "#FF77FF" },
792*5e7646d2SAndroid Build Coastguard Worker { "magenta", "#FF00FF" },
793*5e7646d2SAndroid Build Coastguard Worker { "orange", "#FFA500" },
794*5e7646d2SAndroid Build Coastguard Worker { "red", "#FF0000" },
795*5e7646d2SAndroid Build Coastguard Worker { "silver", "#C0C0C0" },
796*5e7646d2SAndroid Build Coastguard Worker { "white", "#FFFFFF" },
797*5e7646d2SAndroid Build Coastguard Worker { "yellow", "#FFFF00" }
798*5e7646d2SAndroid Build Coastguard Worker };
799*5e7646d2SAndroid Build Coastguard Worker
800*5e7646d2SAndroid Build Coastguard Worker
801*5e7646d2SAndroid Build Coastguard Worker (void)data;
802*5e7646d2SAndroid Build Coastguard Worker
803*5e7646d2SAndroid Build Coastguard Worker if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerColorantValue) &&
804*5e7646d2SAndroid Build Coastguard Worker packet->object_type == CUPS_ASN1_OCTET_STRING)
805*5e7646d2SAndroid Build Coastguard Worker {
806*5e7646d2SAndroid Build Coastguard Worker /*
807*5e7646d2SAndroid Build Coastguard Worker * Get colorant...
808*5e7646d2SAndroid Build Coastguard Worker */
809*5e7646d2SAndroid Build Coastguard Worker
810*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerColorantValueOffset];
811*5e7646d2SAndroid Build Coastguard Worker
812*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerColorantValue.1.%d = \"%s\"\n", i,
813*5e7646d2SAndroid Build Coastguard Worker (char *)packet->object_value.string.bytes);
814*5e7646d2SAndroid Build Coastguard Worker
815*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < num_supplies; j ++)
816*5e7646d2SAndroid Build Coastguard Worker if (supplies[j].colorant == i)
817*5e7646d2SAndroid Build Coastguard Worker {
818*5e7646d2SAndroid Build Coastguard Worker for (k = 0; k < (int)(sizeof(colors) / sizeof(colors[0])); k ++)
819*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(colors[k][0],
820*5e7646d2SAndroid Build Coastguard Worker (char *)packet->object_value.string.bytes))
821*5e7646d2SAndroid Build Coastguard Worker {
822*5e7646d2SAndroid Build Coastguard Worker strlcpy(supplies[j].color, colors[k][1], sizeof(supplies[j].color));
823*5e7646d2SAndroid Build Coastguard Worker break;
824*5e7646d2SAndroid Build Coastguard Worker }
825*5e7646d2SAndroid Build Coastguard Worker }
826*5e7646d2SAndroid Build Coastguard Worker }
827*5e7646d2SAndroid Build Coastguard Worker else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesColorantIndex))
828*5e7646d2SAndroid Build Coastguard Worker {
829*5e7646d2SAndroid Build Coastguard Worker /*
830*5e7646d2SAndroid Build Coastguard Worker * Get colorant index...
831*5e7646d2SAndroid Build Coastguard Worker */
832*5e7646d2SAndroid Build Coastguard Worker
833*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerSuppliesColorantIndexOffset];
834*5e7646d2SAndroid Build Coastguard Worker if (i < 1 || i > CUPS_MAX_SUPPLIES ||
835*5e7646d2SAndroid Build Coastguard Worker packet->object_type != CUPS_ASN1_INTEGER)
836*5e7646d2SAndroid Build Coastguard Worker return;
837*5e7646d2SAndroid Build Coastguard Worker
838*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerSuppliesColorantIndex.1.%d = %d\n", i,
839*5e7646d2SAndroid Build Coastguard Worker packet->object_value.integer);
840*5e7646d2SAndroid Build Coastguard Worker
841*5e7646d2SAndroid Build Coastguard Worker if (i > num_supplies)
842*5e7646d2SAndroid Build Coastguard Worker num_supplies = i;
843*5e7646d2SAndroid Build Coastguard Worker
844*5e7646d2SAndroid Build Coastguard Worker supplies[i - 1].colorant = packet->object_value.integer;
845*5e7646d2SAndroid Build Coastguard Worker }
846*5e7646d2SAndroid Build Coastguard Worker else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesDescription))
847*5e7646d2SAndroid Build Coastguard Worker {
848*5e7646d2SAndroid Build Coastguard Worker /*
849*5e7646d2SAndroid Build Coastguard Worker * Get supply name/description...
850*5e7646d2SAndroid Build Coastguard Worker */
851*5e7646d2SAndroid Build Coastguard Worker
852*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerSuppliesDescriptionOffset];
853*5e7646d2SAndroid Build Coastguard Worker if (i < 1 || i > CUPS_MAX_SUPPLIES ||
854*5e7646d2SAndroid Build Coastguard Worker packet->object_type != CUPS_ASN1_OCTET_STRING)
855*5e7646d2SAndroid Build Coastguard Worker return;
856*5e7646d2SAndroid Build Coastguard Worker
857*5e7646d2SAndroid Build Coastguard Worker if (i > num_supplies)
858*5e7646d2SAndroid Build Coastguard Worker num_supplies = i;
859*5e7646d2SAndroid Build Coastguard Worker
860*5e7646d2SAndroid Build Coastguard Worker switch (charset)
861*5e7646d2SAndroid Build Coastguard Worker {
862*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csASCII :
863*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUTF8 :
864*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUnicodeASCII :
865*5e7646d2SAndroid Build Coastguard Worker strlcpy(supplies[i - 1].name,
866*5e7646d2SAndroid Build Coastguard Worker (char *)packet->object_value.string.bytes,
867*5e7646d2SAndroid Build Coastguard Worker sizeof(supplies[0].name));
868*5e7646d2SAndroid Build Coastguard Worker break;
869*5e7646d2SAndroid Build Coastguard Worker
870*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csISOLatin1 :
871*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUnicodeLatin1 :
872*5e7646d2SAndroid Build Coastguard Worker cupsCharsetToUTF8((cups_utf8_t *)supplies[i - 1].name,
873*5e7646d2SAndroid Build Coastguard Worker (char *)packet->object_value.string.bytes,
874*5e7646d2SAndroid Build Coastguard Worker sizeof(supplies[0].name), CUPS_ISO8859_1);
875*5e7646d2SAndroid Build Coastguard Worker break;
876*5e7646d2SAndroid Build Coastguard Worker
877*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csShiftJIS :
878*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csWindows31J : /* Close enough for our purposes */
879*5e7646d2SAndroid Build Coastguard Worker cupsCharsetToUTF8((cups_utf8_t *)supplies[i - 1].name,
880*5e7646d2SAndroid Build Coastguard Worker (char *)packet->object_value.string.bytes,
881*5e7646d2SAndroid Build Coastguard Worker sizeof(supplies[0].name), CUPS_JIS_X0213);
882*5e7646d2SAndroid Build Coastguard Worker break;
883*5e7646d2SAndroid Build Coastguard Worker
884*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUCS4 :
885*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUTF32 :
886*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUTF32BE :
887*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUTF32LE :
888*5e7646d2SAndroid Build Coastguard Worker cupsUTF32ToUTF8((cups_utf8_t *)supplies[i - 1].name,
889*5e7646d2SAndroid Build Coastguard Worker (cups_utf32_t *)packet->object_value.string.bytes,
890*5e7646d2SAndroid Build Coastguard Worker sizeof(supplies[0].name));
891*5e7646d2SAndroid Build Coastguard Worker break;
892*5e7646d2SAndroid Build Coastguard Worker
893*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUnicode :
894*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUTF16BE :
895*5e7646d2SAndroid Build Coastguard Worker case CUPS_TC_csUTF16LE :
896*5e7646d2SAndroid Build Coastguard Worker utf16_to_utf8((cups_utf8_t *)supplies[i - 1].name,
897*5e7646d2SAndroid Build Coastguard Worker packet->object_value.string.bytes,
898*5e7646d2SAndroid Build Coastguard Worker packet->object_value.string.num_bytes,
899*5e7646d2SAndroid Build Coastguard Worker sizeof(supplies[0].name), charset == CUPS_TC_csUTF16LE);
900*5e7646d2SAndroid Build Coastguard Worker break;
901*5e7646d2SAndroid Build Coastguard Worker
902*5e7646d2SAndroid Build Coastguard Worker default :
903*5e7646d2SAndroid Build Coastguard Worker /*
904*5e7646d2SAndroid Build Coastguard Worker * If we get here, the printer is using an unknown character set and
905*5e7646d2SAndroid Build Coastguard Worker * we just want to copy characters that look like ASCII...
906*5e7646d2SAndroid Build Coastguard Worker */
907*5e7646d2SAndroid Build Coastguard Worker
908*5e7646d2SAndroid Build Coastguard Worker {
909*5e7646d2SAndroid Build Coastguard Worker char *src, *dst; /* Pointers into strings */
910*5e7646d2SAndroid Build Coastguard Worker
911*5e7646d2SAndroid Build Coastguard Worker /*
912*5e7646d2SAndroid Build Coastguard Worker * Loop safe because both the object_value and supplies char arrays
913*5e7646d2SAndroid Build Coastguard Worker * are CUPS_SNMP_MAX_STRING elements long.
914*5e7646d2SAndroid Build Coastguard Worker */
915*5e7646d2SAndroid Build Coastguard Worker
916*5e7646d2SAndroid Build Coastguard Worker for (src = (char *)packet->object_value.string.bytes,
917*5e7646d2SAndroid Build Coastguard Worker dst = supplies[i - 1].name;
918*5e7646d2SAndroid Build Coastguard Worker *src;
919*5e7646d2SAndroid Build Coastguard Worker src ++)
920*5e7646d2SAndroid Build Coastguard Worker {
921*5e7646d2SAndroid Build Coastguard Worker if ((*src & 0x80) || *src < ' ' || *src == 0x7f)
922*5e7646d2SAndroid Build Coastguard Worker *dst++ = '?';
923*5e7646d2SAndroid Build Coastguard Worker else
924*5e7646d2SAndroid Build Coastguard Worker *dst++ = *src;
925*5e7646d2SAndroid Build Coastguard Worker }
926*5e7646d2SAndroid Build Coastguard Worker
927*5e7646d2SAndroid Build Coastguard Worker *dst = '\0';
928*5e7646d2SAndroid Build Coastguard Worker }
929*5e7646d2SAndroid Build Coastguard Worker break;
930*5e7646d2SAndroid Build Coastguard Worker }
931*5e7646d2SAndroid Build Coastguard Worker
932*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerSuppliesDescription.1.%d = \"%s\"\n", i,
933*5e7646d2SAndroid Build Coastguard Worker supplies[i - 1].name);
934*5e7646d2SAndroid Build Coastguard Worker
935*5e7646d2SAndroid Build Coastguard Worker }
936*5e7646d2SAndroid Build Coastguard Worker else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesLevel))
937*5e7646d2SAndroid Build Coastguard Worker {
938*5e7646d2SAndroid Build Coastguard Worker /*
939*5e7646d2SAndroid Build Coastguard Worker * Get level...
940*5e7646d2SAndroid Build Coastguard Worker */
941*5e7646d2SAndroid Build Coastguard Worker
942*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerSuppliesLevelOffset];
943*5e7646d2SAndroid Build Coastguard Worker if (i < 1 || i > CUPS_MAX_SUPPLIES ||
944*5e7646d2SAndroid Build Coastguard Worker packet->object_type != CUPS_ASN1_INTEGER)
945*5e7646d2SAndroid Build Coastguard Worker return;
946*5e7646d2SAndroid Build Coastguard Worker
947*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerSuppliesLevel.1.%d = %d\n", i,
948*5e7646d2SAndroid Build Coastguard Worker packet->object_value.integer);
949*5e7646d2SAndroid Build Coastguard Worker
950*5e7646d2SAndroid Build Coastguard Worker if (i > num_supplies)
951*5e7646d2SAndroid Build Coastguard Worker num_supplies = i;
952*5e7646d2SAndroid Build Coastguard Worker
953*5e7646d2SAndroid Build Coastguard Worker supplies[i - 1].level = packet->object_value.integer;
954*5e7646d2SAndroid Build Coastguard Worker }
955*5e7646d2SAndroid Build Coastguard Worker else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesMaxCapacity) &&
956*5e7646d2SAndroid Build Coastguard Worker !(quirks & CUPS_SNMP_CAPACITY))
957*5e7646d2SAndroid Build Coastguard Worker {
958*5e7646d2SAndroid Build Coastguard Worker /*
959*5e7646d2SAndroid Build Coastguard Worker * Get max capacity...
960*5e7646d2SAndroid Build Coastguard Worker */
961*5e7646d2SAndroid Build Coastguard Worker
962*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerSuppliesMaxCapacityOffset];
963*5e7646d2SAndroid Build Coastguard Worker if (i < 1 || i > CUPS_MAX_SUPPLIES ||
964*5e7646d2SAndroid Build Coastguard Worker packet->object_type != CUPS_ASN1_INTEGER)
965*5e7646d2SAndroid Build Coastguard Worker return;
966*5e7646d2SAndroid Build Coastguard Worker
967*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerSuppliesMaxCapacity.1.%d = %d\n", i,
968*5e7646d2SAndroid Build Coastguard Worker packet->object_value.integer);
969*5e7646d2SAndroid Build Coastguard Worker
970*5e7646d2SAndroid Build Coastguard Worker if (i > num_supplies)
971*5e7646d2SAndroid Build Coastguard Worker num_supplies = i;
972*5e7646d2SAndroid Build Coastguard Worker
973*5e7646d2SAndroid Build Coastguard Worker if (supplies[i - 1].max_capacity == 0 &&
974*5e7646d2SAndroid Build Coastguard Worker packet->object_value.integer > 0)
975*5e7646d2SAndroid Build Coastguard Worker supplies[i - 1].max_capacity = packet->object_value.integer;
976*5e7646d2SAndroid Build Coastguard Worker }
977*5e7646d2SAndroid Build Coastguard Worker else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesClass))
978*5e7646d2SAndroid Build Coastguard Worker {
979*5e7646d2SAndroid Build Coastguard Worker /*
980*5e7646d2SAndroid Build Coastguard Worker * Get marker class...
981*5e7646d2SAndroid Build Coastguard Worker */
982*5e7646d2SAndroid Build Coastguard Worker
983*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerSuppliesClassOffset];
984*5e7646d2SAndroid Build Coastguard Worker if (i < 1 || i > CUPS_MAX_SUPPLIES ||
985*5e7646d2SAndroid Build Coastguard Worker packet->object_type != CUPS_ASN1_INTEGER)
986*5e7646d2SAndroid Build Coastguard Worker return;
987*5e7646d2SAndroid Build Coastguard Worker
988*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerSuppliesClass.1.%d = %d\n", i,
989*5e7646d2SAndroid Build Coastguard Worker packet->object_value.integer);
990*5e7646d2SAndroid Build Coastguard Worker
991*5e7646d2SAndroid Build Coastguard Worker if (i > num_supplies)
992*5e7646d2SAndroid Build Coastguard Worker num_supplies = i;
993*5e7646d2SAndroid Build Coastguard Worker
994*5e7646d2SAndroid Build Coastguard Worker supplies[i - 1].sclass = packet->object_value.integer;
995*5e7646d2SAndroid Build Coastguard Worker }
996*5e7646d2SAndroid Build Coastguard Worker else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesType))
997*5e7646d2SAndroid Build Coastguard Worker {
998*5e7646d2SAndroid Build Coastguard Worker /*
999*5e7646d2SAndroid Build Coastguard Worker * Get marker type...
1000*5e7646d2SAndroid Build Coastguard Worker */
1001*5e7646d2SAndroid Build Coastguard Worker
1002*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerSuppliesTypeOffset];
1003*5e7646d2SAndroid Build Coastguard Worker if (i < 1 || i > CUPS_MAX_SUPPLIES ||
1004*5e7646d2SAndroid Build Coastguard Worker packet->object_type != CUPS_ASN1_INTEGER)
1005*5e7646d2SAndroid Build Coastguard Worker return;
1006*5e7646d2SAndroid Build Coastguard Worker
1007*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerSuppliesType.1.%d = %d\n", i,
1008*5e7646d2SAndroid Build Coastguard Worker packet->object_value.integer);
1009*5e7646d2SAndroid Build Coastguard Worker
1010*5e7646d2SAndroid Build Coastguard Worker if (i > num_supplies)
1011*5e7646d2SAndroid Build Coastguard Worker num_supplies = i;
1012*5e7646d2SAndroid Build Coastguard Worker
1013*5e7646d2SAndroid Build Coastguard Worker supplies[i - 1].type = packet->object_value.integer;
1014*5e7646d2SAndroid Build Coastguard Worker }
1015*5e7646d2SAndroid Build Coastguard Worker else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesSupplyUnit))
1016*5e7646d2SAndroid Build Coastguard Worker {
1017*5e7646d2SAndroid Build Coastguard Worker /*
1018*5e7646d2SAndroid Build Coastguard Worker * Get units for capacity...
1019*5e7646d2SAndroid Build Coastguard Worker */
1020*5e7646d2SAndroid Build Coastguard Worker
1021*5e7646d2SAndroid Build Coastguard Worker i = packet->object_name[prtMarkerSuppliesSupplyUnitOffset];
1022*5e7646d2SAndroid Build Coastguard Worker if (i < 1 || i > CUPS_MAX_SUPPLIES ||
1023*5e7646d2SAndroid Build Coastguard Worker packet->object_type != CUPS_ASN1_INTEGER)
1024*5e7646d2SAndroid Build Coastguard Worker return;
1025*5e7646d2SAndroid Build Coastguard Worker
1026*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG2: prtMarkerSuppliesSupplyUnit.1.%d = %d\n", i,
1027*5e7646d2SAndroid Build Coastguard Worker packet->object_value.integer);
1028*5e7646d2SAndroid Build Coastguard Worker
1029*5e7646d2SAndroid Build Coastguard Worker if (i > num_supplies)
1030*5e7646d2SAndroid Build Coastguard Worker num_supplies = i;
1031*5e7646d2SAndroid Build Coastguard Worker
1032*5e7646d2SAndroid Build Coastguard Worker if (packet->object_value.integer == CUPS_TC_percent)
1033*5e7646d2SAndroid Build Coastguard Worker supplies[i - 1].max_capacity = 100;
1034*5e7646d2SAndroid Build Coastguard Worker }
1035*5e7646d2SAndroid Build Coastguard Worker }
1036*5e7646d2SAndroid Build Coastguard Worker
1037*5e7646d2SAndroid Build Coastguard Worker
1038*5e7646d2SAndroid Build Coastguard Worker /*
1039*5e7646d2SAndroid Build Coastguard Worker * 'utf16_to_utf8()' - Convert UTF-16 text to UTF-8.
1040*5e7646d2SAndroid Build Coastguard Worker */
1041*5e7646d2SAndroid Build Coastguard Worker
1042*5e7646d2SAndroid Build Coastguard Worker static void
utf16_to_utf8(cups_utf8_t * dst,const unsigned char * src,size_t srcsize,size_t dstsize,int le)1043*5e7646d2SAndroid Build Coastguard Worker utf16_to_utf8(
1044*5e7646d2SAndroid Build Coastguard Worker cups_utf8_t *dst, /* I - Destination buffer */
1045*5e7646d2SAndroid Build Coastguard Worker const unsigned char *src, /* I - Source string */
1046*5e7646d2SAndroid Build Coastguard Worker size_t srcsize, /* I - Size of source string */
1047*5e7646d2SAndroid Build Coastguard Worker size_t dstsize, /* I - Size of destination buffer */
1048*5e7646d2SAndroid Build Coastguard Worker int le) /* I - Source is little-endian? */
1049*5e7646d2SAndroid Build Coastguard Worker {
1050*5e7646d2SAndroid Build Coastguard Worker cups_utf32_t ch, /* Current character */
1051*5e7646d2SAndroid Build Coastguard Worker temp[CUPS_SNMP_MAX_STRING],
1052*5e7646d2SAndroid Build Coastguard Worker /* UTF-32 string */
1053*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into UTF-32 string */
1054*5e7646d2SAndroid Build Coastguard Worker
1055*5e7646d2SAndroid Build Coastguard Worker
1056*5e7646d2SAndroid Build Coastguard Worker for (ptr = temp; srcsize >= 2;)
1057*5e7646d2SAndroid Build Coastguard Worker {
1058*5e7646d2SAndroid Build Coastguard Worker if (le)
1059*5e7646d2SAndroid Build Coastguard Worker ch = (cups_utf32_t)(src[0] | (src[1] << 8));
1060*5e7646d2SAndroid Build Coastguard Worker else
1061*5e7646d2SAndroid Build Coastguard Worker ch = (cups_utf32_t)((src[0] << 8) | src[1]);
1062*5e7646d2SAndroid Build Coastguard Worker
1063*5e7646d2SAndroid Build Coastguard Worker src += 2;
1064*5e7646d2SAndroid Build Coastguard Worker srcsize -= 2;
1065*5e7646d2SAndroid Build Coastguard Worker
1066*5e7646d2SAndroid Build Coastguard Worker if (ch >= 0xd800 && ch <= 0xdbff && srcsize >= 2)
1067*5e7646d2SAndroid Build Coastguard Worker {
1068*5e7646d2SAndroid Build Coastguard Worker /*
1069*5e7646d2SAndroid Build Coastguard Worker * Multi-word UTF-16 char...
1070*5e7646d2SAndroid Build Coastguard Worker */
1071*5e7646d2SAndroid Build Coastguard Worker
1072*5e7646d2SAndroid Build Coastguard Worker cups_utf32_t lch; /* Lower word */
1073*5e7646d2SAndroid Build Coastguard Worker
1074*5e7646d2SAndroid Build Coastguard Worker
1075*5e7646d2SAndroid Build Coastguard Worker if (le)
1076*5e7646d2SAndroid Build Coastguard Worker lch = (cups_utf32_t)(src[0] | (src[1] << 8));
1077*5e7646d2SAndroid Build Coastguard Worker else
1078*5e7646d2SAndroid Build Coastguard Worker lch = (cups_utf32_t)((src[0] << 8) | src[1]);
1079*5e7646d2SAndroid Build Coastguard Worker
1080*5e7646d2SAndroid Build Coastguard Worker if (lch >= 0xdc00 && lch <= 0xdfff)
1081*5e7646d2SAndroid Build Coastguard Worker {
1082*5e7646d2SAndroid Build Coastguard Worker src += 2;
1083*5e7646d2SAndroid Build Coastguard Worker srcsize -= 2;
1084*5e7646d2SAndroid Build Coastguard Worker
1085*5e7646d2SAndroid Build Coastguard Worker ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
1086*5e7646d2SAndroid Build Coastguard Worker }
1087*5e7646d2SAndroid Build Coastguard Worker }
1088*5e7646d2SAndroid Build Coastguard Worker
1089*5e7646d2SAndroid Build Coastguard Worker if (ptr < (temp + CUPS_SNMP_MAX_STRING - 1))
1090*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ch;
1091*5e7646d2SAndroid Build Coastguard Worker }
1092*5e7646d2SAndroid Build Coastguard Worker
1093*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
1094*5e7646d2SAndroid Build Coastguard Worker
1095*5e7646d2SAndroid Build Coastguard Worker cupsUTF32ToUTF8(dst, temp, (int)dstsize);
1096*5e7646d2SAndroid Build Coastguard Worker }
1097