pappl icon indicating copy to clipboard operation
pappl copied to clipboard

Support for string/text-style vendor options

Open tillkamppeter opened this issue 3 years ago • 9 comments

In some cases a printer has options of string or text style and not enumerated choice, for example passwords, PINs, fax numbers, individual watermark text, ...

In the test Printer Application you even use such an option for the label printer, which you call "vendor-text". You create it by the following lines in the driver data callback:

  driver_data->vendor[4]  = "vendor-text";
  [...]
  ippAddString(*driver_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "vendor-text-default", NULL, "Hello, World!");

There is no vendor-text-supported attribute created.

Only due to the fact that we also want to save individual data (like the "Installable Options" in the PostScript Printer Application) in the state file you consider vendor options without ...-supported attribute as such individual data.

Now we need a solution to offer BOTH text/string-style options (where one can set a default in the web interface) AND saving individual data in the state file.

Or is there perhaps a useful ...-supported attribute which one could add to the vendor-text option to let it appear in the web interface and not breaking it?

tillkamppeter avatar Jan 22 '21 10:01 tillkamppeter

My suggestion to solve this: One could use the option name for distinguishing between string options and hidden options for holding individual data. Any awkward prefix which is accepted in an IPP attribute name but not to be expected as an option name to be understood and used by a user.

tillkamppeter avatar Jun 11 '21 21:06 tillkamppeter

I have a better suggestion: Use the data type IPP_TAG_STRING (string with additional length parameter, can but not must contain '\0' bytes) for hidden data and IPP_TAG_TEXT for text/string-style user-settable options:

  // Vendor option
  driver_data->vendor[4]  = "private-job-pin";
  ippAddString(*driver_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "private-job-pin-default", NULL, "0000");
  // Hidden data: Installable options
  inst_opt = "Tray2=Installed Finisher=Stapler";
  driver_data->vendor[5]  = "installable-options";
  ippAddOctetString(*driver_attrs, IPP_TAG_PRINTER, "installable-options-default", inst_opt, strlen(inst_opt));

WDYT?

tillkamppeter avatar Jun 11 '21 22:06 tillkamppeter

I have implemented it now as this patch: support-text-string-vendor-options.patch.txt

Here I use the IPP_TAG_STRING (octet string) data type for hidden data, like my "Installable Options" and IPP_TAG_TEXT for regular, user-settable, text/string options. Due to the nature of state files being plain text and so not able to carry binary data, the data type IPP_TAG_STRING is useless for regular options/attributes and can be easily abused for the hidden data saving.

In the state file I precede the name with an asterisk (*) so that it is marked as hidden data and gets loaded again as IPP_TAG_STRING data type.

The patch also contains a use of this in the sample application and there it works correctly.

I am testing currently with the PostScript Printer Application.

tillkamppeter avatar Jun 12 '21 08:06 tillkamppeter

Now I have done a real-life test of this by modifying the PostScript Printer Application appropriately and also adding support for the CUPS PPD extension of custom option values. This works as expected.

It especially allows now to print on PostScript printers from Ricoh and OEM with the PIN-based features of Locked Print, Document Server, and User Code, where the PIN is entered as a custom string/text option.

Here is the patch for the current GIT state of the PostScript Printer Application: ppd-cups-custom-options-support.patch.txt

tillkamppeter avatar Jun 13 '21 13:06 tillkamppeter

here is a sample PPD file of a Ricoh printer to test the above: Ricoh-Aficio_2035_PS.ppd.txt

The three options for PIN-based printing allow entering arbitrary PINs as sustom strings, using the appropriate CUPS extension for PPD files. With the patches for PAPPL and for the PostScript Printer Application we have a hidden vendor option for holding the settings for the installable options and we have input lines for the PINs in the "Printing Defaults".

Simply add the sample PPD vis the "Add PPD files" button on the main screen of the web interface.

tillkamppeter avatar Jun 13 '21 19:06 tillkamppeter

@tillkamppeter i will look at this but at the moment my PAPPL work is on the back burner as I finish up some stuff for a customer. Probably be a week or so before I can get back to this…

michaelrsweet avatar Jun 14 '21 13:06 michaelrsweet

Update of the patch on the PostScript Printer Application to match with further development: ppd-cups-custom-options-support.patch.txt

tillkamppeter avatar Jun 19 '21 06:06 tillkamppeter

For testing the current Snap of the PostScript Printer Application in the Snap Store includes the patches attached here, allowing to use PIN-protected secure printing on all Ricoh (and OEM) PostScript printers.

tillkamppeter avatar Jun 19 '21 06:06 tillkamppeter

With the addition of support for CUPS' PPD extension for custom option settings the patch for the Snap of the PostScript Printer Application only needs to provide the adaptations to work together with the patched PAPPL. Here is the new patch for the PostScript Printer Application: support-new-pappl-string-options.patch.txt

tillkamppeter avatar Jun 20 '21 21:06 tillkamppeter

@tillkamppeter What are you actually trying to do with this? You don't need this patch for custom text options ("vendor-xxx-default" saves the value, "job-creation-attributes-supported" lists the "vendor-xxx" attribute name), and honestly there is little point to exposing some of these printer-specific options (beyond defaults) because no IPP client will ever support them.

michaelrsweet avatar Oct 08 '22 17:10 michaelrsweet

The reason for the patch is to have both the possibility for hidden state data of the driver, in my case the installable accessory configuration and the possibility to get free-formed-string-style options into the web interface. As IPP clients will usually not support the vendor options of the legacy (like ole printers which need a driver) or specialty (like Braille embossers, ...) printers, it is important that they all appear in the web interface, including the free-form-string ones. This way one can do for example secure printing on an old non-driverless-IPP printer. And in addition, the web interface does not expose any driver-internal state data which the user is not supposed to edit. So we have two types of vendor string options, hidden ones and exposed ones.

A name-prefix-based solution as I suggested earlier here would also do the trick, too, but I have no idea which name prefix would be suitable, as it has to be legal in IPP but somehow awkward that manufacturers/driver developers would not use it for actual attributes.

tillkamppeter avatar Oct 08 '22 18:10 tillkamppeter

So for installable options we need to support "xxx-configured" instead of "xxx-default" for the value. These won't be free-form, just keywords ("xxx-configured" is a keyword and "xxx-suppported" is a list of keywords) and boolean ("xxx-configured" is a boolean). But since that is really specific to PPD-based drivers where you can't query the printer for its installed options, and non-PPD drivers typically don't have such things, I'm not keen on adding a lot of infrastructure for an edge case. Better to add printer-specific data and a custom web page for configuring installable options than to treat them as vendor-specific job options (which they aren't).

For vendor text options, I've just pushed a fix:

[master 5c687d8] Fix support for vendor text options (Issue #142)

michaelrsweet avatar Oct 08 '22 20:10 michaelrsweet

Better to add printer-specific data and a custom web page for configuring installable options than to treat them as vendor-specific job options (which they aren't).

The custom web page is already there in the PostScript Printer Application, the "Device Settings", but how can I save the choices which the user has made there into the state file and load them from the state file in the next session of the Printer Application?

tillkamppeter avatar Oct 08 '22 21:10 tillkamppeter

And one additional aspect of saving data which is not option settings in the state file is that Printer Applications can host any type of printer driver which could have really weird settings which are not mappable to IPP, but it is useful to set them in the web interface, like I have added a web interface page for the installable accessories and want to save what the user has chosen there.

For example if we take Gutenprint, a native Printer Application of Gutenprint. Gutenprint has tons of options, many being numerical. Trying to squeeze this into IPP attribute data types is awkward, not as awkward as cramming this into PPD option data types but it is awkward. We could instead create one or more extra pages in the web interface and put nice widgets onto them to make the adjustments and then we must save these settings somehow, as it would be awkward for the user to set them again and again for each new session. We could even allow the user to save named sets of settings and AFAIK IPP has also a job attribute to select from named presets (I do not remember the name). So then if the user has saved a named set of settings, the get-printer-attributes response would have the name listed in the appropriate ...-supported printer attribute. This way an IPP client can at least choose from the named presets.

Therefore we need a way to save extra (driver-specific) information in the state file which does not appear in any way on the standard web interface pages of PAPPL.

tillkamppeter avatar Oct 08 '22 22:10 tillkamppeter

@tillkamppeter The papplPrinterOpenFile API can be used to save/restore printer-specific state information in a persistent location. The driver callback is responsible for creating/restoring the extension data (part of the pappl_pr_driver_data_t structure), with the delete_callback responsible for freeing the extension data. Your settings/configuration web page would then save the extension data whenever you change it.

WRT Gutenprint, presets ("job-presets-supported") can map to Gutenprint and user-defined named presets, with vendor collection attributes mapping to all of the driver settings for a theoretical "expert" print dialog that provides access to all of the individual settings while the standard print dialog provide access to the presets.

michaelrsweet avatar Oct 09 '22 14:10 michaelrsweet

Could you add an example use/CI test for the papplPrinterOpenFile API to PAPPL's test Printer Application?

tillkamppeter avatar Oct 10 '22 06:10 tillkamppeter

Thanks for the hint, I have checked this papplPrinterOpenFile() function now, and this should work as you described. Perhaps it can even simplify the driver setup in pappl-retrofit then, as I can decide where to load and save the data about the installable accesories, in contrary to the state file where PAPPL determines where it is loaded and saved.

tillkamppeter avatar Oct 10 '22 07:10 tillkamppeter

Thanks a lot for your hint, @michaelrsweet, I have fixed pappl-retrofit (commit OpenPrinting/pappl-retrofit@4a54fb7148e9) appropriately now. So I can remove the patches on PAPPL and pappl-retrofit in my Snaps.

tillkamppeter avatar Oct 16 '22 22:10 tillkamppeter

All the 4 retro-fitting Printer Applications in the Snap Store are appropriately updated now.

Thank you very much.

tillkamppeter avatar Oct 17 '22 10:10 tillkamppeter