1 /*****************************************************************************\
3 hpiom.c - HP I/O message handler
5 (c) 2003-2004 Copyright Hewlett-Packard Development Company, LP
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. Neither the name of Hewlett-Packard nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 \*****************************************************************************/
34 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
47 static const int gnMaxDataSize = 2048;
48 static const int gnMaxCmdOptionSize = 4;
50 static const char gcFrameMarker = '$';
51 static const int gnPadding = 255;
52 static const int gnRequiredSize = 11;
53 static const int gnMinCommandSize = 16;
54 static const int gnMinDecodeSize = 10; // needed six bytes to determine command number,
55 // command length and data length
57 static const int gUV8FrameOffset = 0;
58 static const int gUV16CommandLengthOffset = 1;
59 static const int gUV8UnitNumberOffset = 3;
60 static const int gE8PacketTypeOffset = 4;
61 static const int gUV8CommandNumberOffset = 5;
62 static const int gUV16ReferenceNumberOffset = 6;
63 static const int gUV16DataLengthOffset = 8;
64 static const int gUV8CommandOptionsOffset = 10;
66 static const int gUV8RespFrameOffset = 0;
67 static const int gUV16RespCommandLengthOffset = 1;
68 static const int gUV8RespUnitNumberOffset = 3;
69 static const int gE8RespPacketTypeOffset = 4;
70 static const int gUV8RespCommandNumberOffset = 5;
71 static const int gUV16RespReferenceNumberOffset = 6;
72 static const int gUV16RespDataLengthOffset = 8;
73 static const int gE8RespCompleteOffset = 10;
75 // reserved reference number
77 static const int gnMinRefNum = 0xF000;
78 static const int gnMaxRefNum = 0xFFFD;
80 unsigned short gwSynchRefNum = 0xFFEC;
81 unsigned short gwSynchCompleteRefNum = 0xFFEB;
82 unsigned short gwResetRefNum = 0xFFEA;
84 unsigned short gwPrinterVersionQueryRefNum = 0xFFD0;
85 unsigned short gwPrinterStatusQueryRefNum = 0xFFD1;
86 unsigned short gwPrinterAttributesQueryRefNum = 0xFFD2;
87 unsigned short gwAlignmentQueryRefNum = 0xFFD3;
88 unsigned short gwDeviceIdQueryRefNum = 0xFFDD;
89 unsigned short gwHueCompensationQueryRefNum = 0xFFDE;
93 // printer query command options
95 static const int gnPrinterQueryOptionsSize = 4;
97 static unsigned char gpPrinterVersionQuery[] = { 0x00, 0x00, 0x00, 0x00 }; // 0 - return UV32 version data
98 //static unsigned char gpPrinterStatusQuery[] = { 0x01, 0x00, 0x00, 0x00 }; // 1 - return status string
99 //static unsigned char gpPrinterAttributesQuery[] = { 0x02, 0x00, 0x00, 0x00 }; // 2 - return printer attributes
100 static unsigned char gpAlignmentQuery[] = { 0x03, 0x00, 0x00, 0x00 }; // 3 - return primitive alignment value
101 //static unsigned char gpDeviceIdQuery[] = { 0x0D, 0x00, 0x00, 0x00 }; // 13 - return device id
102 //static unsigned char gpHueCompensationQuery[] = { 0x0E, 0x00, 0x00, 0x00 }; // 14 - return hue compensation
103 static unsigned char gpPenAlignmentQuery[] = { 0x0F, 0x00, 0x00, 0x00 }; // 15 - return pen alignment value
111 unsigned char *lpBuffer,
112 unsigned short wBufferSize,
113 unsigned char unUnitNumber,
117 unsigned short wDataLength,
118 unsigned char *lpCommandOptions,
119 unsigned short wCommandOptionsSize,
121 unsigned short wRefNum
125 int lNumPaddingNeeded = 0;
126 unsigned char *lpTemp = NULL;
128 memset( lpBuffer, 0, wBufferSize );
129 lpBuffer [ gUV8FrameOffset ] = gcFrameMarker;
130 lpBuffer [ gUV8UnitNumberOffset ] = unUnitNumber;
131 lpBuffer [ gE8PacketTypeOffset ] = ePacketType;
132 lpBuffer [ gUV8CommandNumberOffset ] = eCommandNumber;
133 *(short *)(lpBuffer + gUV16DataLengthOffset) = htons(wDataLength);
135 if ( wCommandOptionsSize > 0 )
137 if ( lpCommandOptions )
139 // copy command options to the buffer
140 memcpy(( lpBuffer + gUV8CommandOptionsOffset ), lpCommandOptions, wCommandOptionsSize);
144 // command option is null, fill the buffer with zeros
145 memset(( lpBuffer + gUV8CommandOptionsOffset ), 0, wCommandOptionsSize );
149 // calculate command length and padding if needed
150 *dPacketSize = gnRequiredSize + wCommandOptionsSize;
151 lNumPaddingNeeded = gnMinCommandSize - *dPacketSize;
153 if ( lNumPaddingNeeded > 0 )
155 // move the pointer to the beginning of the padding
156 lpTemp = lpBuffer + gUV8CommandOptionsOffset + wCommandOptionsSize;
158 for (x = 0; x < lNumPaddingNeeded; x++, lpTemp++ )
163 *dPacketSize = gnMinCommandSize;
166 *(short *)(lpBuffer + gUV16CommandLengthOffset) = htons(*dPacketSize);
167 *(short *)(lpBuffer + gUV16ReferenceNumberOffset) = htons(wRefNum ? wRefNum : 1);
169 // add the trailing frame marker
170 lpBuffer[ *dPacketSize - 1 ] = gcFrameMarker;
174 if ((*dPacketSize + wDataLength) > wBufferSize)
176 BUG("unable to fill data buffer EncodeCommand size=%d\n", wDataLength);
182 // copy the data to the end of the command
183 memcpy( lpBuffer + *dPacketSize, lpData, wDataLength );
187 // NULL data pointer, fill the buffer with zeros
188 memset( lpBuffer + *dPacketSize, 0, wDataLength );
191 *dPacketSize += wDataLength;
197 int Synch(int hd, int chan)
201 unsigned char buf[4096];
203 // create the Synch command, send it to the device,
204 // and retrieve absolute credit data from the device.
205 EncodeCommand(buf, sizeof(buf)
217 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &bRet);
222 int SynchComplete(int hd, int chan)
226 unsigned char buf[32];
228 // create the SynchComplete command, send it to the device,
229 // and retrieve absolute credit data from the device.
230 EncodeCommand(buf, sizeof(buf)
239 , gwSynchCompleteRefNum
242 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &bRet);
247 int Reset(int hd, int chan)
251 unsigned char buf[32];
253 // create the Reset command, send it to the device,
254 // and retrieve absolute credit data from the device.
256 EncodeCommand(buf, sizeof(buf)
268 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &bRet);
273 int RetrieveAlignmentValues038(int hd, int chan, LDLGenAlign *pG)
277 unsigned char buf[256];
278 LDLResponseAlign038 *pA;
280 /* Enable responses. */
281 EncodeCommand(buf, sizeof(buf)
292 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
294 /* Write alignment query. */
295 EncodeCommand(buf, sizeof(buf)
302 , gnPrinterQueryOptionsSize
304 , gwAlignmentQueryRefNum
306 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
308 /* Disable responses. */
309 EncodeCommand(buf, sizeof(buf)
320 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
322 /* Read query response. */
323 hpmud_read_channel(hd, chan, buf, sizeof(buf), EXCEPTION_TIMEOUT, &n);
324 pA = (LDLResponseAlign038 *)buf;
325 memset(pG, 0, sizeof(LDLGenAlign));
326 if (pA->h.packet_type == 16)
329 /* Except for bi, convert values from relative to black pen to relative to color. */
330 pG->pen[0].color = 0;
331 pG->pen[0].vert = -pA->c[0];
332 pG->pen[0].horz = -pA->c[1];
333 pG->pen[0].bi = pA->k[2];
334 pG->pen[1].color = 1;
335 pG->pen[1].vert = pA->k[0];
336 pG->pen[1].horz = pA->k[1];
337 pG->pen[1].bi = pA->c[2];
343 int RetrieveAlignmentValues043(int hd, int chan, LDLGenAlign *pG)
347 unsigned char buf[256];
348 LDLResponseAlign043 *pA;
350 /* Enable responses. */
351 EncodeCommand(buf, sizeof(buf)
362 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
364 /* Write alignment query. */
365 EncodeCommand(buf, sizeof(buf)
371 , gpPenAlignmentQuery
372 , gnPrinterQueryOptionsSize
374 , gwAlignmentQueryRefNum
376 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
378 /* Disable responses. */
379 EncodeCommand(buf, sizeof(buf)
390 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
392 hpmud_read_channel(hd, chan, buf, sizeof(buf), EXCEPTION_TIMEOUT, &n);
393 pA = (LDLResponseAlign043 *)buf;
394 memset(pG, 0, sizeof(LDLGenAlign));
395 if (pA->h.packet_type == 16)
397 memcpy(pG, &pA->g, sizeof(LDLGenAlign));
403 uint32_t RetrieveVersion(int hd, int chan)
407 unsigned char buf[256];
408 LDLResponseVersion *pV;
410 /* Enable responses. */
411 EncodeCommand(buf, sizeof(buf)
422 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
424 /* Write lidil version query. */
425 EncodeCommand(buf, sizeof(buf)
431 , gpPrinterVersionQuery
432 , gnPrinterQueryOptionsSize
434 , gwAlignmentQueryRefNum
436 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
438 /* Disable responses. */
439 EncodeCommand(buf, sizeof(buf)
450 hpmud_write_channel(hd, chan, buf, dPacketSize, EXCEPTION_TIMEOUT, &n);
452 hpmud_read_channel(hd, chan, buf, sizeof(buf), EXCEPTION_TIMEOUT, &n);
453 pV = (LDLResponseVersion *)buf;
454 if (pV->h.packet_type == 16)
456 version = ntohl(pV->ldlversion);
457 fprintf(stdout, "lidil version = %x\n", version);
464 * Return value = (black | photo) to color vertical alignment offset, error = -1.
466 * All alignment values may be zero if pen(s) were never aligned. Valid values
467 * may range from -30 to +30.
469 int ReadHPVertAlign(int hd)
471 int channel, n, i, x2colorVert=-1;
475 if (hpmud_open_channel(hd, "PRINT", &channel) != HPMUD_R_OK)
477 BUG("unable to open print channel ReadHPVertAlign\n");
481 if (Synch(hd, channel)==0)
483 BUG("unable to write sync ReadHPVertAlign\n");
487 if (SynchComplete(hd, channel)==0)
489 BUG("unable to write sync complete ReadHPVertAlign\n");
493 if (Reset(hd, channel)==0)
495 BUG("unable to write reset ReadHPVertAlign\n");
499 if ((ver = RetrieveVersion(hd, channel))==0)
501 BUG("unable to read version ReadHPVertAlign\n");
506 RetrieveAlignmentValues043(hd, channel, &ga);
508 RetrieveAlignmentValues038(hd, channel, &ga);
515 if (ga.pen[i].color == 0 || ga.pen[i].color == 2)
517 x2colorVert = ga.pen[i].vert; /* (black | photo) to color offset */
518 BUG("%s alignment: vert=%d horz=%d bi=%d x2c=%d\n", (ga.pen[i].color==0) ? "black" : "photo", ga.pen[i].vert, ga.pen[i].horz, ga.pen[i].bi, x2colorVert);
526 hpmud_close_channel(hd, channel);
531 #endif // HAVE_LIBHPIP