[cups.general] Getting capability info from IPP printers

Till Kamppeter till.kamppeter at gmail.com
Tue Feb 19 07:47:50 PST 2013


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






More information about the cups mailing list