| [13] | 1 | Using RPUPortQuery & RPUPortSet | 
|---|
|  | 2 | =============================== | 
|---|
| [3] | 3 |  | 
|---|
| [13] | 4 | These functions return or accept a buffer (passed as a REXX string) which | 
|---|
|  | 5 | contains the current port configuration data as raw bytes.  The format of | 
|---|
|  | 6 | this data depends on the port driver which controls the particular port | 
|---|
|  | 7 | being queried or set. | 
|---|
|  | 8 |  | 
|---|
|  | 9 | The data formats for several common port drivers are described below. | 
|---|
|  | 10 |  | 
|---|
|  | 11 | NOTE: All data must be in raw byte (or 'character') form.  This is the form | 
|---|
|  | 12 | outputted by functions like D2C() or X2C(). | 
|---|
|  | 13 |  | 
|---|
|  | 14 | In addition, multi-byte integer values like (U)LONG and (U)SHORT must | 
|---|
|  | 15 | be passed in little-endian order. | 
|---|
|  | 16 |  | 
|---|
|  | 17 | i.e. | 
|---|
|  | 18 | To convert <number> to USHORT:  ushort = REVERSE( X2C( D2X( number, 4 ))) | 
|---|
|  | 19 | To convert <number> to ULONG:   ulong  = REVERSE( X2C( D2X( number, 8 ))) | 
|---|
|  | 20 |  | 
|---|
| [14] | 21 | Fixed-length string (character array) fields MUST append a 0 byte to | 
|---|
|  | 22 | the end of the string value, and SHOULD pad the rest of the array (up | 
|---|
|  | 23 | to the defined length) with 0 bytes as well. | 
|---|
| [13] | 24 |  | 
|---|
| [14] | 25 |  | 
|---|
| [13] | 26 | SERIAL.PDR, PARALLEL.PDR | 
|---|
|  | 27 | ------------------------ | 
|---|
|  | 28 |  | 
|---|
| [3] | 29 | The standard serial and parallel port drivers do not support the SplPdSet API. | 
|---|
|  | 30 |  | 
|---|
|  | 31 |  | 
|---|
| [13] | 32 | PAR1284.PDR | 
|---|
|  | 33 | ----------- | 
|---|
|  | 34 |  | 
|---|
|  | 35 | The high-speed BIDI parallel port (PAR1284) driver uses a data structure with | 
|---|
|  | 36 | the following format (information taken from IBM DDK headers): | 
|---|
|  | 37 |  | 
|---|
|  | 38 | typedef struct _PORTSETTINGS{ | 
|---|
| [3] | 39 | ULONG   signature;           /* Must be 0x52464E49 ('INFR')               */ | 
|---|
|  | 40 | ULONG   ulVersion;           /* Must be 0x00000001                        */ | 
|---|
|  | 41 | ULONG   flStatus;            /* Status flags:                             */ | 
|---|
|  | 42 | /* 0x00000001  BIDI_Q_PORT set (bidi enabled)*/ | 
|---|
|  | 43 | /* 0x00000002  Set after 1st attempt at bidi */ | 
|---|
|  | 44 | /* 0x00000004  Port connected to print queue */ | 
|---|
|  | 45 | /* 0x00000008  Port already open             */ | 
|---|
|  | 46 | /* 0x00000010  Port open in progress         */ | 
|---|
|  | 47 | /* 0x00000020  SplPdOpen being processed     */ | 
|---|
|  | 48 | /* 0x00000040  SplPdClose being processed    */ | 
|---|
|  | 49 | /* 0x00000080  XlateCmd has more alerts left */ | 
|---|
|  | 50 | /* 0x00000100  New printer or powered off    */ | 
|---|
|  | 51 | /* 0x00000200  Set when deviceId was checked */ | 
|---|
|  | 52 | /*             after first good write to a   */ | 
|---|
|  | 53 | /*             unidirectional printer.       */ | 
|---|
|  | 54 | /* 0x00000400  Set when last write was sent  */ | 
|---|
|  | 55 | /*             using ECP mode cmd channel.   */ | 
|---|
|  | 56 | /* 0x00000800  Set when printer put in bidi  */ | 
|---|
|  | 57 | /*             mode and DeviceID received.   */ | 
|---|
|  | 58 | /* 0x00001000  Set when CommStatChange alert */ | 
|---|
|  | 59 | /*             was posted to spooler.        */ | 
|---|
|  | 60 | /*             Cleared after BIDI_Q_PORT     */ | 
|---|
|  | 61 | /* 0x00002000  Set when CommStatChange alert */ | 
|---|
|  | 62 | /*             should not be set             */ | 
|---|
|  | 63 | /* 0x00004000  Set when port has a network   */ | 
|---|
|  | 64 | /*             connection                    */ | 
|---|
|  | 65 | ULONG   flBidiCapabilities;  /* PRTPORT.flBidiCapabilities _CAPS_     */ | 
|---|
|  | 66 | ULONG   flBidiProtocol;      /* PRTPORT.flBidiProtocol _TYPE_         */ | 
|---|
|  | 67 | ULONG   flJob;               /* PRTSW.flJob flags                     */ | 
|---|
|  | 68 | ULONG   flDevice;            /* PRTSW.flDevice flags                  */ | 
|---|
|  | 69 | ULONG   ulModeSelected;      /* Mode selected by user(see PARMODE_)   */ | 
|---|
|  | 70 | ULONG   ulCurrentMode;       /* Current mode of port(see CURMODE_)    */ | 
|---|
|  | 71 | BOOL    fShareAccess;        /* Share port with DOS/Windows           */ | 
|---|
|  | 72 | ULONG   ulPrintTimeOut;      /* Seconds to continue to retry job      */ | 
|---|
|  | 73 | /*  write request in SplPdWrite().       */ | 
|---|
|  | 74 | /*  Default: 45 seconds                  */ | 
|---|
|  | 75 | ULONG   ulNoQueryTimeOut;    /* Seconds from last query until         */ | 
|---|
|  | 76 | /*  port drops printer connection        */ | 
|---|
|  | 77 | /*  Default: 180 seconds                 */ | 
|---|
|  | 78 | ULONG   ulNoJobTimeOut;      /* Seconds from last job sent until      */ | 
|---|
|  | 79 | /*  port drops printer connection        */ | 
|---|
|  | 80 | /*  NOTE: Connection can be dropped      */ | 
|---|
|  | 81 | /*        sooner if PDR receives         */ | 
|---|
|  | 82 | /*        BIDI_NOTIFY_ENDJOBCONNECT      */ | 
|---|
|  | 83 | /*        This is used if we lose        */ | 
|---|
|  | 84 | /*        a job acknowledgement so       */ | 
|---|
|  | 85 | /*        that other Apps can use the    */ | 
|---|
|  | 86 | /*        infrared port.                 */ | 
|---|
|  | 87 | /*  Default: 300 seconds                 */ | 
|---|
|  | 88 | /*                                       */ | 
|---|
|  | 89 | PPTIMEOUTCHANNEL TimeOut;    /* Read and Write timeouts               */ | 
|---|
|  | 90 | /*                                       */ | 
|---|
|  | 91 | /*                                       */ | 
|---|
|  | 92 | /* The following ulpsz fields are        */ | 
|---|
|  | 93 | /*  offsets from the beginning of        */ | 
|---|
|  | 94 | /*  this PORTSETTINGS structure to       */ | 
|---|
|  | 95 | /*  the variable length strings.         */ | 
|---|
|  | 96 | /* This allows us to pass the buffer     */ | 
|---|
|  | 97 | /*  intact to PrtQuery and PrtSet,       */ | 
|---|
|  | 98 | /*  even across the network.             */ | 
|---|
|  | 99 | /* All strings are packed immediately    */ | 
|---|
|  | 100 | /*  after the fixed-length PORTSETTINGS  */ | 
|---|
|  | 101 | /*  structure.                           */ | 
|---|
|  | 102 | /*                                       */ | 
|---|
|  | 103 | /* An offset of 0 means no string        */ | 
|---|
|  | 104 | /*                                       */ | 
|---|
|  | 105 | ULONG   ulpszPortName;       /* -> name of port info is for           */ | 
|---|
|  | 106 | ULONG   ulpszDeviceID;       /* -> 1284 deviceID for printer on port  */ | 
|---|
|  | 107 | } PORTSETTINGS, *PPORTSETTINGS; | 
|---|
|  | 108 |  | 
|---|
| [13] | 109 | /* Structure for setting timeouts                                        */ | 
|---|
|  | 110 | /*                                                                       */ | 
|---|
|  | 111 | /* This port driver will assume that bidi capable printers can accept    */ | 
|---|
|  | 112 | /* data at a reasonable rate, so the WriteIdle timeout will default to a */ | 
|---|
|  | 113 | /* small value(like 15 seconds). The actual WriteTimeout specified by    */ | 
|---|
|  | 114 | /* the user can be larger, and our PdWrite API will handle retrying      */ | 
|---|
|  | 115 | /* requests that do not complete.  However, we will always have a        */ | 
|---|
|  | 116 | /* ParReadThread for each bidi port, and this read will typically be     */ | 
|---|
|  | 117 | /* queued up after the write. When a write completes(even if only        */ | 
|---|
|  | 118 | /* partial buffer was sent), the queued read request will reverse the    */ | 
|---|
|  | 119 | /* channel and check for data coming from the printer.  This read must   */ | 
|---|
|  | 120 | /* not take a long time(to avoid performance degradation for writes).    */ | 
|---|
|  | 121 | /*                                                                       */ | 
|---|
|  | 122 | /* We set a small ReadInterrupt timeout( about 200 ms default ) so that  */ | 
|---|
|  | 123 | /* if no data is waiting to be read, the read request returns and lets   */ | 
|---|
|  | 124 | /* the write request be processed.                                       */ | 
|---|
|  | 125 | /*                                                                       */ | 
|---|
|  | 126 | /* We set a longer ReadIdle timeout( 1000 ms ) to attempt to get the     */ | 
|---|
|  | 127 | /* entire buffer from the peripheral if there is data waiting to be sent */ | 
|---|
|  | 128 | /* to the host.                                                          */ | 
|---|
|  | 129 | /*                                                                       */ | 
|---|
|  | 130 | /* For now, we set the WriteIdle and WriteInterrupt timeouts to be the   */ | 
|---|
|  | 131 | /* same.  This means we will always return within the WriteIdle timeout  */ | 
|---|
|  | 132 | /* value specified.                                                      */ | 
|---|
|  | 133 | /*                                                                       */ | 
|---|
| [3] | 134 | typedef struct _PPTIMEOUTCHANNEL{ | 
|---|
|  | 135 | ULONG   ulReadIdleTimeOut;  // millisecs DD has to complete entire Read | 
|---|
|  | 136 | ULONG   ulReadIntTimeOut;   // millisecs DD waits for Read interrupt | 
|---|
|  | 137 | ULONG   ulWriteIdleTimeOut; // millisecs DD has to complete entire Write | 
|---|
|  | 138 | ULONG   ulWriteIntTimeOut;  // millisecs DD waits for Write interrupt | 
|---|
|  | 139 | ULONG   ulLogChannel;   // 1=use data channel, 2=use address channel | 
|---|
|  | 140 | } PPTIMEOUTCHANNEL, *PPPTIMEOUTCHANNEL; | 
|---|
|  | 141 |  | 
|---|
| [13] | 142 | (Refer to the header file wpshell\src\wpsh\par1284\pdrtypes.h from the IBM | 
|---|
|  | 143 | DDK for more information.) | 
|---|
| [3] | 144 |  | 
|---|
|  | 145 |  | 
|---|
| [13] | 146 | CUPS.PDR | 
|---|
|  | 147 | -------- | 
|---|
| [3] | 148 |  | 
|---|
| [13] | 149 | The eCups port driver (CUPS.PDR) uses the following port settings structure: | 
|---|
| [3] | 150 |  | 
|---|
|  | 151 | typedef struct _PORTSETTINGS { | 
|---|
|  | 152 | CHAR     szHost[ 65 ];       // CUPS server hostname/IP | 
|---|
|  | 153 | CHAR     szQueue[ 65 ];      // CUPS printer queue name | 
|---|
|  | 154 | } PORTSETTINGS, *PPORTSETTINGS; | 
|---|
|  | 155 |  | 
|---|
| [13] | 156 | (At least version 1.04 of CUPS.PDR is required.) | 
|---|
| [3] | 157 |  | 
|---|
|  | 158 |  | 
|---|
| [13] | 159 | SMB.PDR | 
|---|
|  | 160 | ------- | 
|---|
| [3] | 161 |  | 
|---|
| [13] | 162 | The Samba port driver (SMB.PDR) takes a single 256-byte buffer.  This | 
|---|
|  | 163 | buffer must take the following format: | 
|---|
| [3] | 164 |  | 
|---|
| [13] | 165 | host#printer#workgroup#userid#copies#password | 
|---|
|  | 166 |  | 
|---|
|  | 167 | All fields are required; those whose values are unspecified must be left | 
|---|
|  | 168 | empty.  (Replace each field name above with its corresponding value.) | 
|---|
|  | 169 | The buffer is padded with 0 bytes to a length of 256 as needed. | 
|---|
|  | 170 |  | 
|---|
|  | 171 | The 'password' field is a hexadecimal string; all others are standard | 
|---|
|  | 172 | character strings. | 
|---|
|  | 173 |  | 
|---|
|  | 174 | For example, to set the following configuration: | 
|---|
|  | 175 | host:      PRINTSRV | 
|---|
|  | 176 | printer:   LJET01 | 
|---|
|  | 177 | workgroup: <none> | 
|---|
|  | 178 | userid:    mrmuffin | 
|---|
|  | 179 | password:  blueberry | 
|---|
|  | 180 | copies:    1 | 
|---|
|  | 181 |  | 
|---|
|  | 182 | In REXX: | 
|---|
|  | 183 | params = 'PRINTSRV#LJET01##mrmuffin#1#626C75656265727279' | 
|---|
|  | 184 | IF LENGTH( params <= 256 ) THEN DO | 
|---|
|  | 185 | buffer = params || COPIES('00'x, 256 - LENGTH( params )) | 
|---|
|  | 186 | CALL RPUPortSet 'SMB', buffer | 
|---|
|  | 187 | END | 
|---|
|  | 188 |  | 
|---|
| [14] | 189 | (At least version 1.03 of SMB.PDR is required.) | 
|---|
|  | 190 |  | 
|---|