Discussion:
Getting capability info from IPP printers
Till Kamppeter
2013-02-19 15:47:28 UTC
Permalink
Hi,

to allow driverless printiung on network-connected printers, especially
from mobile devices I want to poll capability information from the
printer, where I want to support IPP printers with known PDLs, like
PostScript, PCL, IPP Everywhere, ... The program should then
automatically generate a PPD file or at least select the most suitable
generic one, depending on how much info the printer provides.

Using ipptool of CUPS I have no problem to poll info from IPP printers,
running

ipptool -X <IPP URI of the printer> cap.ipptool

cap.ipptool contains:

----------
IGNORE-ERRORS yes
{
NAME "Get printer attributes using Get-Printer-Attributes"
OPERATION Get-Printer-Attributes
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR keyword requested-attributes
job-template,printer-description,printer-resolution-supported,print-color-mode-supported,print-quality-supported,media-supported,media-default,media-ready,output-bin-supported,finishings-supported,color-supported,sides-supported,number-up-supported,page-ranges-supported,all,media-col-database
}
----------

Now I want to poll with my own C program. It contains:

----------
char *uri;
http_t *http;
ipp_t *request, *response;
int i;
char scheme[10], userpass[1024], host_name[1024], resource[1024];
static const char * const requested_attrs[] =
{
"printer-description",
"document-format-supported",
"color-supported",
"pages-per-minute",
"pages-per-minute-color",
"media-supported",
"media-ready",
"media-default",
"media-type-supported",
"media-source-supported",
"media-col-database",
"sides-supported",
"sides-default",
"output-bin-supported",
"output-bin-default",
"finishings-supported",
"finishings-default",
"print-color-mode-supported",
"print-color-mode-default",
"output-mode-supported",
"output-mode-default",
"print-quality-supported",
"print-quality-default",
"printer-resolution-supported",
"printer-resolution-default",
"copies-supported",
"copies-default",
"all"
};
uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
scheme, sizeof(scheme),
userpass, sizeof(userpass),
host_name, sizeof(host_name),
&(port),
resource, sizeof(resource));
if (uri_status != HTTP_URI_OK)
goto fail;
if ((http = httpConnect(host_name, port)) ==
NULL) {
goto fail;
}
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
/*ippSetRequestId(request, (CUPS_RAND() % 1000) * 137 + 1);*/
/*ippAddSeparator(request);*/
/*ippSetVersion(request, 1, 1);*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, "utf-8");*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, "en");*/
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, p->uri);
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());*/
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requested-attributes",
sizeof(requested_attrs) / sizeof(requested_attrs[0]),
NULL, requested_attrs);
/*int status = cupsSendRequest(http, request, resource,
ippLength(request));
response = cupsGetResponse(http, resource);*/
response = cupsDoRequest(http, request, resource);
if (response == NULL) {
httpClose(http);
goto fail;
}
printf("cups-browsed: Remote printer %s: %s (%s)\n",
p->uri, ippErrorString(cupsLastError()),
cupsLastErrorString());
ipp_attribute_t *attr;
attr = ippFirstAttribute(response);
while (attr) {
printf("Attr: %s\n",
ippGetName(attr));
for (i = 0; i < ippGetCount(attr); i ++)
printf("Value: %s\n",
ippGetString(attr, i, NULL));
attr = ippNextAttribute(response);
}
attr = ippFindAttribute(response,
"document-format-supported",
IPP_TAG_ZERO);
if (attr)
for (i = 0; i < ippGetCount(attr); i ++)
printf("Format: %s\n",
ippGetString(attr, i, NULL));
else
printf("Not found.\n");

/* Clean up */
ippDelete(response);
httpClose(http);
fail:
----------

With this I always get client-error-bad-request, independent whwther I
run it as shown here or whatever combination of lines which are
currently commented out I activated. I tried with several HP printers
(HP Color LaserJet CM3530 MFP, HP LaserJet P3005, HP OfficeJet Pro 8500
A910) and the Canon iR-ADV C5000s-B1, all with the same result, and all
work with ipptool. I also tried to remove and re-add items from the list
of requested attributes.

Note: I am using this code only for directly talking with network
printers, not for remote CUPS queues.

Any idea what I am doing wrong?

Till
Till Kamppeter
2013-02-19 17:08:46 UTC
Permalink
Attached is the output of

sudo tcpdump -s0 -U -w <file>.tcp tcp port ipp

for both cases.

ipptool.tcp is of ipptool, cups-browsed.tcp of my C program.

Till
Post by Till Kamppeter
Hi,
to allow driverless printiung on network-connected printers, especially
from mobile devices I want to poll capability information from the
printer, where I want to support IPP printers with known PDLs, like
PostScript, PCL, IPP Everywhere, ... The program should then
automatically generate a PPD file or at least select the most suitable
generic one, depending on how much info the printer provides.
Using ipptool of CUPS I have no problem to poll info from IPP printers,
running
ipptool -X <IPP URI of the printer> cap.ipptool
----------
IGNORE-ERRORS yes
{
NAME "Get printer attributes using Get-Printer-Attributes"
OPERATION Get-Printer-Attributes
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR keyword requested-attributes
job-template,printer-description,printer-resolution-supported,print-color-mode-supported,print-quality-supported,media-supported,media-default,media-ready,output-bin-supported,finishings-supported,color-supported,sides-supported,number-up-supported,page-ranges-supported,all,media-col-database
}
----------
----------
char *uri;
http_t *http;
ipp_t *request, *response;
int i;
char scheme[10], userpass[1024], host_name[1024], resource[1024];
static const char * const requested_attrs[] =
{
"printer-description",
"document-format-supported",
"color-supported",
"pages-per-minute",
"pages-per-minute-color",
"media-supported",
"media-ready",
"media-default",
"media-type-supported",
"media-source-supported",
"media-col-database",
"sides-supported",
"sides-default",
"output-bin-supported",
"output-bin-default",
"finishings-supported",
"finishings-default",
"print-color-mode-supported",
"print-color-mode-default",
"output-mode-supported",
"output-mode-default",
"print-quality-supported",
"print-quality-default",
"printer-resolution-supported",
"printer-resolution-default",
"copies-supported",
"copies-default",
"all"
};
uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
scheme, sizeof(scheme),
userpass, sizeof(userpass),
host_name, sizeof(host_name),
&(port),
resource, sizeof(resource));
if (uri_status != HTTP_URI_OK)
goto fail;
if ((http = httpConnect(host_name, port)) ==
NULL) {
goto fail;
}
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
/*ippSetRequestId(request, (CUPS_RAND() % 1000) * 137 + 1);*/
/*ippAddSeparator(request);*/
/*ippSetVersion(request, 1, 1);*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, "utf-8");*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, "en");*/
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, p->uri);
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());*/
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requested-attributes",
sizeof(requested_attrs) / sizeof(requested_attrs[0]),
NULL, requested_attrs);
/*int status = cupsSendRequest(http, request, resource,
ippLength(request));
response = cupsGetResponse(http, resource);*/
response = cupsDoRequest(http, request, resource);
if (response == NULL) {
httpClose(http);
goto fail;
}
printf("cups-browsed: Remote printer %s: %s (%s)\n",
p->uri, ippErrorString(cupsLastError()),
cupsLastErrorString());
ipp_attribute_t *attr;
attr = ippFirstAttribute(response);
while (attr) {
printf("Attr: %s\n",
ippGetName(attr));
for (i = 0; i < ippGetCount(attr); i ++)
printf("Value: %s\n",
ippGetString(attr, i, NULL));
attr = ippNextAttribute(response);
}
attr = ippFindAttribute(response,
"document-format-supported",
IPP_TAG_ZERO);
if (attr)
for (i = 0; i < ippGetCount(attr); i ++)
printf("Format: %s\n",
ippGetString(attr, i, NULL));
else
printf("Not found.\n");
/* Clean up */
ippDelete(response);
httpClose(http);
----------
With this I always get client-error-bad-request, independent whwther I
run it as shown here or whatever combination of lines which are
currently commented out I activated. I tried with several HP printers
(HP Color LaserJet CM3530 MFP, HP LaserJet P3005, HP OfficeJet Pro 8500
A910) and the Canon iR-ADV C5000s-B1, all with the same result, and all
work with ipptool. I also tried to remove and re-add items from the list
of requested attributes.
Note: I am using this code only for directly talking with network
printers, not for remote CUPS queues.
Any idea what I am doing wrong?
Till
Michael Sweet
2013-02-19 17:35:14 UTC
Permalink
Till,

First, you can trim requested-attributes to just:

job-template
printer-description
media-col-database

since all of the -default and -supported values are covered by the job-template group.

Second, you need to use IPP_TAG_KEYWORD when you add the requested-attributes strings, not IPP_TAG_NAME...
Post by Till Kamppeter
Hi,
to allow driverless printiung on network-connected printers, especially
from mobile devices I want to poll capability information from the
printer, where I want to support IPP printers with known PDLs, like
PostScript, PCL, IPP Everywhere, ... The program should then
automatically generate a PPD file or at least select the most suitable
generic one, depending on how much info the printer provides.
Using ipptool of CUPS I have no problem to poll info from IPP printers,
running
ipptool -X <IPP URI of the printer> cap.ipptool
----------
IGNORE-ERRORS yes
{
NAME "Get printer attributes using Get-Printer-Attributes"
OPERATION Get-Printer-Attributes
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR keyword requested-attributes
job-template,printer-description,printer-resolution-supported,print-color-mode-supported,print-quality-supported,media-supported,media-default,media-ready,output-bin-supported,finishings-supported,color-supported,sides-supported,number-up-supported,page-ranges-supported,all,media-col-database
}
----------
----------
char *uri;
http_t *http;
ipp_t *request, *response;
int i;
char scheme[10], userpass[1024], host_name[1024], resource[1024];
static const char * const requested_attrs[] =
{
"printer-description",
"document-format-supported",
"color-supported",
"pages-per-minute",
"pages-per-minute-color",
"media-supported",
"media-ready",
"media-default",
"media-type-supported",
"media-source-supported",
"media-col-database",
"sides-supported",
"sides-default",
"output-bin-supported",
"output-bin-default",
"finishings-supported",
"finishings-default",
"print-color-mode-supported",
"print-color-mode-default",
"output-mode-supported",
"output-mode-default",
"print-quality-supported",
"print-quality-default",
"printer-resolution-supported",
"printer-resolution-default",
"copies-supported",
"copies-default",
"all"
};
uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
scheme, sizeof(scheme),
userpass, sizeof(userpass),
host_name, sizeof(host_name),
&(port),
resource, sizeof(resource));
if (uri_status != HTTP_URI_OK)
goto fail;
if ((http = httpConnect(host_name, port)) ==
NULL) {
goto fail;
}
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
/*ippSetRequestId(request, (CUPS_RAND() % 1000) * 137 + 1);*/
/*ippAddSeparator(request);*/
/*ippSetVersion(request, 1, 1);*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, "utf-8");*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, "en");*/
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, p->uri);
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());*/
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requested-attributes",
sizeof(requested_attrs) / sizeof(requested_attrs[0]),
NULL, requested_attrs);
/*int status = cupsSendRequest(http, request, resource,
ippLength(request));
response = cupsGetResponse(http, resource);*/
response = cupsDoRequest(http, request, resource);
if (response == NULL) {
httpClose(http);
goto fail;
}
printf("cups-browsed: Remote printer %s: %s (%s)\n",
p->uri, ippErrorString(cupsLastError()),
cupsLastErrorString());
ipp_attribute_t *attr;
attr = ippFirstAttribute(response);
while (attr) {
printf("Attr: %s\n",
ippGetName(attr));
for (i = 0; i < ippGetCount(attr); i ++)
printf("Value: %s\n",
ippGetString(attr, i, NULL));
attr = ippNextAttribute(response);
}
attr = ippFindAttribute(response,
"document-format-supported",
IPP_TAG_ZERO);
if (attr)
for (i = 0; i < ippGetCount(attr); i ++)
printf("Format: %s\n",
ippGetString(attr, i, NULL));
else
printf("Not found.\n");
/* Clean up */
ippDelete(response);
httpClose(http);
----------
With this I always get client-error-bad-request, independent whwther I
run it as shown here or whatever combination of lines which are
currently commented out I activated. I tried with several HP printers
(HP Color LaserJet CM3530 MFP, HP LaserJet P3005, HP OfficeJet Pro 8500
A910) and the Canon iR-ADV C5000s-B1, all with the same result, and all
work with ipptool. I also tried to remove and re-add items from the list
of requested attributes.
Note: I am using this code only for directly talking with network
printers, not for remote CUPS queues.
Any idea what I am doing wrong?
Till
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair
Till Kamppeter
2013-02-19 17:49:26 UTC
Permalink
It is working now! Thank you very much.

Till
Post by Till Kamppeter
Till,
job-template
printer-description
media-col-database
since all of the -default and -supported values are covered by the job-template group.
Second, you need to use IPP_TAG_KEYWORD when you add the requested-attributes strings, not IPP_TAG_NAME...
Till Kamppeter
2013-02-19 18:22:16 UTC
Permalink
Another question:

If I do not set the IPP version to 1.1 via

ippSetVersion(request, 1, 1);

the printer reports

server-error-version-not-supported

How do I find the correct IPP version for the request if I do not know
the printer's IPP version? Is there an automatic mode? Can I get a list
of all IPP versions which the currently running CUPS supports so that I
can simply go through all of them beginning with the newest until the
printer accepts?

Which version CUPS uses by default?

My CUPS version is 1.6.1 in Ubuntu Raring.

Till
Post by Till Kamppeter
Till,
job-template
printer-description
media-col-database
since all of the -default and -supported values are covered by the job-template group.
Second, you need to use IPP_TAG_KEYWORD when you add the requested-attributes strings, not IPP_TAG_NAME...
Post by Till Kamppeter
Hi,
to allow driverless printiung on network-connected printers, especially
from mobile devices I want to poll capability information from the
printer, where I want to support IPP printers with known PDLs, like
PostScript, PCL, IPP Everywhere, ... The program should then
automatically generate a PPD file or at least select the most suitable
generic one, depending on how much info the printer provides.
Using ipptool of CUPS I have no problem to poll info from IPP printers,
running
ipptool -X <IPP URI of the printer> cap.ipptool
----------
IGNORE-ERRORS yes
{
NAME "Get printer attributes using Get-Printer-Attributes"
OPERATION Get-Printer-Attributes
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR keyword requested-attributes
job-template,printer-description,printer-resolution-supported,print-color-mode-supported,print-quality-supported,media-supported,media-default,media-ready,output-bin-supported,finishings-supported,color-supported,sides-supported,number-up-supported,page-ranges-supported,all,media-col-database
}
----------
----------
char *uri;
http_t *http;
ipp_t *request, *response;
int i;
char scheme[10], userpass[1024], host_name[1024], resource[1024];
static const char * const requested_attrs[] =
{
"printer-description",
"document-format-supported",
"color-supported",
"pages-per-minute",
"pages-per-minute-color",
"media-supported",
"media-ready",
"media-default",
"media-type-supported",
"media-source-supported",
"media-col-database",
"sides-supported",
"sides-default",
"output-bin-supported",
"output-bin-default",
"finishings-supported",
"finishings-default",
"print-color-mode-supported",
"print-color-mode-default",
"output-mode-supported",
"output-mode-default",
"print-quality-supported",
"print-quality-default",
"printer-resolution-supported",
"printer-resolution-default",
"copies-supported",
"copies-default",
"all"
};
uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
scheme, sizeof(scheme),
userpass, sizeof(userpass),
host_name, sizeof(host_name),
&(port),
resource, sizeof(resource));
if (uri_status != HTTP_URI_OK)
goto fail;
if ((http = httpConnect(host_name, port)) ==
NULL) {
goto fail;
}
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
/*ippSetRequestId(request, (CUPS_RAND() % 1000) * 137 + 1);*/
/*ippAddSeparator(request);*/
/*ippSetVersion(request, 1, 1);*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, "utf-8");*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, "en");*/
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, p->uri);
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());*/
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requested-attributes",
sizeof(requested_attrs) / sizeof(requested_attrs[0]),
NULL, requested_attrs);
/*int status = cupsSendRequest(http, request, resource,
ippLength(request));
response = cupsGetResponse(http, resource);*/
response = cupsDoRequest(http, request, resource);
if (response == NULL) {
httpClose(http);
goto fail;
}
printf("cups-browsed: Remote printer %s: %s (%s)\n",
p->uri, ippErrorString(cupsLastError()),
cupsLastErrorString());
ipp_attribute_t *attr;
attr = ippFirstAttribute(response);
while (attr) {
printf("Attr: %s\n",
ippGetName(attr));
for (i = 0; i < ippGetCount(attr); i ++)
printf("Value: %s\n",
ippGetString(attr, i, NULL));
attr = ippNextAttribute(response);
}
attr = ippFindAttribute(response,
"document-format-supported",
IPP_TAG_ZERO);
if (attr)
for (i = 0; i < ippGetCount(attr); i ++)
printf("Format: %s\n",
ippGetString(attr, i, NULL));
else
printf("Not found.\n");
/* Clean up */
ippDelete(response);
httpClose(http);
----------
With this I always get client-error-bad-request, independent whwther I
run it as shown here or whatever combination of lines which are
currently commented out I activated. I tried with several HP printers
(HP Color LaserJet CM3530 MFP, HP LaserJet P3005, HP OfficeJet Pro 8500
A910) and the Canon iR-ADV C5000s-B1, all with the same result, and all
work with ipptool. I also tried to remove and re-add items from the list
of requested attributes.
Note: I am using this code only for directly talking with network
printers, not for remote CUPS queues.
Any idea what I am doing wrong?
Till
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
Michael Sweet
2013-02-19 18:38:26 UTC
Permalink
Till,
Post by Till Kamppeter
If I do not set the IPP version to 1.1 via
ippSetVersion(request, 1, 1);
the printer reports
server-error-version-not-supported
How do I find the correct IPP version for the request if I do not know
the printer's IPP version?
If you get server-error-version-not-supported, retry the query using IPP/1.1.
Post by Till Kamppeter
Is there an automatic mode?
No.
Post by Till Kamppeter
Can I get a list of all IPP versions which the currently running CUPS supports so that I can simply go through all of them beginning with the newest until the printer accepts?
No, there is no API for that, but if you are using the newer ippSetVersion API then you have to be running CUPS 1.6 or later, which supports IPP/1.x and IPP/2.x.

But really in this case you just care about what the printer supports - just try 2.0 and if that fails try 1.1. Don't bother trying 1.0, it just means the printer manufacturer didn't update beyond that experimental (and obsolete) version and it is highly unlikely you will be able to do anything useful with it. 2.1 and 2.2 just target different protocol feature sets, but fundamentally anything you do as a client in a 2.1 or 2.2 request can be done in a 2.0 request - the version numbers just identify (grossly) what the server can do, with the IPP Everywhere and JPS3 changes that came after IPP/2.0 allowing you to learn about supported features (document object, etc.) more easily.
Post by Till Kamppeter
Which version CUPS uses by default?
ippGetVersion will do it, but for CUPS 1.6 and later you'll always get 2.0 from ippNewRequest.
Post by Till Kamppeter
My CUPS version is 1.6.1 in Ubuntu Raring.
Have you looked at the new destination APIs? They are really intended to support this kind of usage (discovery, query for capabilities, and support job submission and management) without you needing to write a lot of extra code...
Post by Till Kamppeter
Till
Post by Till Kamppeter
Till,
job-template
printer-description
media-col-database
since all of the -default and -supported values are covered by the job-template group.
Second, you need to use IPP_TAG_KEYWORD when you add the requested-attributes strings, not IPP_TAG_NAME...
Post by Till Kamppeter
Hi,
to allow driverless printiung on network-connected printers, especially
from mobile devices I want to poll capability information from the
printer, where I want to support IPP printers with known PDLs, like
PostScript, PCL, IPP Everywhere, ... The program should then
automatically generate a PPD file or at least select the most suitable
generic one, depending on how much info the printer provides.
Using ipptool of CUPS I have no problem to poll info from IPP printers,
running
ipptool -X <IPP URI of the printer> cap.ipptool
----------
IGNORE-ERRORS yes
{
NAME "Get printer attributes using Get-Printer-Attributes"
OPERATION Get-Printer-Attributes
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR keyword requested-attributes
job-template,printer-description,printer-resolution-supported,print-color-mode-supported,print-quality-supported,media-supported,media-default,media-ready,output-bin-supported,finishings-supported,color-supported,sides-supported,number-up-supported,page-ranges-supported,all,media-col-database
}
----------
----------
char *uri;
http_t *http;
ipp_t *request, *response;
int i;
char scheme[10], userpass[1024], host_name[1024], resource[1024];
static const char * const requested_attrs[] =
{
"printer-description",
"document-format-supported",
"color-supported",
"pages-per-minute",
"pages-per-minute-color",
"media-supported",
"media-ready",
"media-default",
"media-type-supported",
"media-source-supported",
"media-col-database",
"sides-supported",
"sides-default",
"output-bin-supported",
"output-bin-default",
"finishings-supported",
"finishings-default",
"print-color-mode-supported",
"print-color-mode-default",
"output-mode-supported",
"output-mode-default",
"print-quality-supported",
"print-quality-default",
"printer-resolution-supported",
"printer-resolution-default",
"copies-supported",
"copies-default",
"all"
};
uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
scheme, sizeof(scheme),
userpass, sizeof(userpass),
host_name, sizeof(host_name),
&(port),
resource, sizeof(resource));
if (uri_status != HTTP_URI_OK)
goto fail;
if ((http = httpConnect(host_name, port)) ==
NULL) {
goto fail;
}
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
/*ippSetRequestId(request, (CUPS_RAND() % 1000) * 137 + 1);*/
/*ippAddSeparator(request);*/
/*ippSetVersion(request, 1, 1);*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, "utf-8");*/
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, "en");*/
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, p->uri);
/*ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());*/
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requested-attributes",
sizeof(requested_attrs) / sizeof(requested_attrs[0]),
NULL, requested_attrs);
/*int status = cupsSendRequest(http, request, resource,
ippLength(request));
response = cupsGetResponse(http, resource);*/
response = cupsDoRequest(http, request, resource);
if (response == NULL) {
httpClose(http);
goto fail;
}
printf("cups-browsed: Remote printer %s: %s (%s)\n",
p->uri, ippErrorString(cupsLastError()),
cupsLastErrorString());
ipp_attribute_t *attr;
attr = ippFirstAttribute(response);
while (attr) {
printf("Attr: %s\n",
ippGetName(attr));
for (i = 0; i < ippGetCount(attr); i ++)
printf("Value: %s\n",
ippGetString(attr, i, NULL));
attr = ippNextAttribute(response);
}
attr = ippFindAttribute(response,
"document-format-supported",
IPP_TAG_ZERO);
if (attr)
for (i = 0; i < ippGetCount(attr); i ++)
printf("Format: %s\n",
ippGetString(attr, i, NULL));
else
printf("Not found.\n");
/* Clean up */
ippDelete(response);
httpClose(http);
----------
With this I always get client-error-bad-request, independent whwther I
run it as shown here or whatever combination of lines which are
currently commented out I activated. I tried with several HP printers
(HP Color LaserJet CM3530 MFP, HP LaserJet P3005, HP OfficeJet Pro 8500
A910) and the Canon iR-ADV C5000s-B1, all with the same result, and all
work with ipptool. I also tried to remove and re-add items from the list
of requested attributes.
Note: I am using this code only for directly talking with network
printers, not for remote CUPS queues.
Any idea what I am doing wrong?
Till
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair
Till Kamppeter
2013-02-20 10:49:51 UTC
Permalink
Thank you very much.

I am no doing the first query with IPP 2.0 and downgrade to 1.1 in case
of failure.

Till
Post by Michael Sweet
If you get server-error-version-not-supported, retry the query using IPP/1.1.
Post by Till Kamppeter
Is there an automatic mode?
No.
Post by Till Kamppeter
Can I get a list of all IPP versions which the currently running CUPS supports so that I can simply go through all of them beginning with the newest until the printer accepts?
No, there is no API for that, but if you are using the newer ippSetVersion API then you have to be running CUPS 1.6 or later, which supports IPP/1.x and IPP/2.x.
But really in this case you just care about what the printer supports - just try 2.0 and if that fails try 1.1. Don't bother trying 1.0, it just means the printer manufacturer didn't update beyond that experimental (and obsolete) version and it is highly unlikely you will be able to do anything useful with it. 2.1 and 2.2 just target different protocol feature sets, but fundamentally anything you do as a client in a 2.1 or 2.2 request can be done in a 2.0 request - the version numbers just identify (grossly) what the server can do, with the IPP Everywhere and JPS3 changes that came after IPP/2.0 allowing you to learn about supported features (document object, etc.) more easily.
Post by Till Kamppeter
Which version CUPS uses by default?
ippGetVersion will do it, but for CUPS 1.6 and later you'll always get 2.0 from ippNewRequest.
Post by Till Kamppeter
My CUPS version is 1.6.1 in Ubuntu Raring.
Have you looked at the new destination APIs? They are really intended to support this kind of usage (discovery, query for capabilities, and support job submission and management) without you needing to write a lot of extra code...
Till Kamppeter
2013-02-20 12:41:28 UTC
Permalink
Post by Michael Sweet
Have you looked at the new destination APIs? They are really intended to support this kind of usage (discovery, query for capabilities, and support job submission and management) without you needing to write a lot of extra code...
I have looked into these APIs now, but it seems that they only work with
remote CUPS queues and not with network printers. Or did I overlook
something?

Till
Michael Sweet
2013-02-20 18:02:47 UTC
Permalink
Till,

The discovery APIs are designed to only find CUPS and IPP Everywhere-compatible printers at this time, although conceptually they could be made to find others (including maybe statically-configured printers in ~/.cups?)

All of the destination APIs will work with any IPP printer - just create a CUPS destination and set the printer-uri-supported value in the options array to have them look at the specific printer you are using.
Post by Till Kamppeter
Post by Michael Sweet
Have you looked at the new destination APIs? They are really intended to support this kind of usage (discovery, query for capabilities, and support job submission and management) without you needing to write a lot of extra code...
I have looked into these APIs now, but it seems that they only work with
remote CUPS queues and not with network printers. Or did I overlook
something?
Till
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair
Till Kamppeter
2013-02-20 18:21:28 UTC
Permalink
Post by Michael Sweet
The discovery APIs are designed to only find CUPS and IPP Everywhere-compatible printers at this time, although conceptually they could be made to find others (including maybe statically-configured printers in ~/.cups?)
All of the destination APIs will work with any IPP printer - just create a CUPS destination and set the printer-uri-supported value in the options array to have them look at the specific printer you are using.
This means that I have to create a local (raw) CUPS queue at first, set
the URI pointing to the printer, and then I can investigate the printer.
After that I either generate and add a PPD (IPP Everywhere printer), do
nothing (remote CUPS queue), or remove the queue again (unknown
printer). Is this the correct way to proceed?

Till
Michael Sweet
2013-02-20 19:59:45 UTC
Permalink
Till,

Assuming this is all for IPP printers, you should be able to do this:

cups_dest_t mydest = { "somename", NULL, 0, NULL };

mydest.num_options = cupsAddOption("printer-uri-supported", "ipp://printer-address/printer-path", 0, &mydest.options);

cups_dinfo_t *mydinfo = cupsCopyDestInfo(CUPS_HTTP_DEFAULT, &mydest);

// do something with mydest and mydinfo

cupsFreeDestInfo(mydinfo);
cupsFreeOptions(mydest.num_options, mydest.options);

Also you can use cupsAddDest to manage a list of destinations; the key bit is to have "printer-uri-supported" point to the printer - no local queue is required for these functions to work, the local queue just provides support for spooling and conversion.

Reminder: the current code is optimized for IPP Everywhere/CUPS implementations so it is entirely possible you will run into issues if you try to print to a "lesser" implementation of IPP... Query stuff should work just fine, though.
Post by Till Kamppeter
Post by Michael Sweet
The discovery APIs are designed to only find CUPS and IPP Everywhere-compatible printers at this time, although conceptually they could be made to find others (including maybe statically-configured printers in ~/.cups?)
All of the destination APIs will work with any IPP printer - just create a CUPS destination and set the printer-uri-supported value in the options array to have them look at the specific printer you are using.
This means that I have to create a local (raw) CUPS queue at first, set
the URI pointing to the printer, and then I can investigate the printer.
After that I either generate and add a PPD (IPP Everywhere printer), do
nothing (remote CUPS queue), or remove the queue again (unknown
printer). Is this the correct way to proceed?
Till
_______________________________________________
cups mailing list
http://lists.easysw.com/mailman/listinfo/cups
_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair

Loading...