/************************************************************************** * LPRng IFHP Filter * Copyright 1994-1999 Patrick Powell, San Diego, CA **************************************************************************/ /**** HEADER *****/ static char *const _id = "$Id: checkcode.c,v 1.10 2003/11/17 16:55:36 papowell Exp papowell $"; #include "ifhp.h" /**** ENDINCLUDE ****/ /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Check out the HP PCL 5 reference manual set; it includes the PJL manual which contains a complete (as far as I know) listing of status/error codes. In case you don't have the manual handy, here's some code I used to handle the status codes. The code should be fairly obvious. Free feel to use it. Eelco van Asperen / Erasmus University Rotterdam ----------------------------/ Informatievoorziening en Automatisering FEW vanasperen@facb.few.eur.nl / PObox 1738, 3000 DR Rotterdam, The Netherlands The header file, pjlcode.h: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ #define PJLC_GROUP(c) ((c)/1000) #define PJLC_CODE(c) ((c)%1000) #define PJLC_X(c) ((c/100)%10) #define PJLC_YY(c) ((c)%100) #define PJLC_XX(c) ((c/10)%100) #define PJLC_Y(c) ((c)%10) typedef struct code_t { int code; char *msg; int flag; } code_t; /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- And the actual code, pjlcode.c: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ code_t groupcode[] = { { 10, "Informational", 0}, #define XTrayCodeYYMediaCode 1 { 11, "Background Paper Loading", XTrayCodeYYMediaCode }, #define XTrayCodeYYTrayStatus 2 { 12, "Background Paper Tray Status", XTrayCodeYYTrayStatus }, #define XXOutputYBinStatus 3 { 15, "Output Bin Status", XXOutputYBinStatus }, { 20, "PJL Parser Errors", 0}, { 25, "PJL Parser Warning", 0}, { 27, "PJL Semantic Errors", 0}, { 30, "Auto Continuable Conditions", 0}, { 32, "PUL File System Errors", 0}, { 35, "Possible Operator Intervention Conditions", 0}, { 40, "Operator Intervention Required", 0}, { 41, "Paper Mount Required", /* "Foreground Paper Mount" */ XTrayCodeYYMediaCode }, #define XJamCountYYJamLocation 4 { 42, "Paper Jam", XJamCountYYJamLocation }, #define XExtDeviceYYCode 5 { 43, "External Paper Handling Device Errors", XExtDeviceYYCode }, #define XJamCountYY4000Location 6 { 44, "LJ4000 Paper Jam", XJamCountYY4000Location }, { 50, "Hardware Errors", 0}, { 0, 0, 0}, }; static code_t pjlmsg[] = { /* Informational Message */ { 10000, "powersave mode", 0}, { 10001, "Ready Online", 0}, { 10002, "Ready Offline", 0}, { 10003, "Warming Up", 0}, { 10004, "Self Test", 0}, { 10005, "Reset", 0}, { 10006, "Toner Low", 0}, { 10007, "Cancelling Job", 0}, { 10010, "Status Buffer Overflow", 0}, { 10011, "auxiliary IO initialisation", 0}, { 10013, "self test", 0}, { 10014, "printing test", 0}, { 10015, "typeface list", 0}, { 10016, "engine test", 0}, { 10017, "demo page", 0}, { 10018, "menu reset", 0}, { 10019, "reset active IO", 0}, { 10020, "reset all IO", 0}, { 10022, "config page", 0}, { 10023, "processing job", 0}, { 10024, "waiting", 0}, { 10027, "remove paper from printer", 0}, { 10029, "formfeeding", 0}, { 10030, "job message displayed", 0}, { 10999, "warming up", 0}, /* 11xxx (Background Paper Loading Messages */ { 11304, "tray 3 empty (tray 3=LC)", 0}, /* Background paper tray status */ { 12201, "tray 2 open", 0}, { 12202, "tray 2 lifting", 0}, { 12301, "tray 3 open", 0}, { 12302, "tray 3 lifting", 0}, /* PJL Parser Error */ { 20001, "generic syntax error", 0}, { 20002, "unsupported command", 0}, { 20004, "unsupported personality/system", 0}, { 20006, "illegal character or line terminated by the UEL command", 0}, { 20007, "whitespace or linefeed missing after closing quotes", 0}, { 20008, "invalid character in an alphanumeric value", 0}, { 20009, "invalid character in a numeric value", 0}, { 20010, "invalid character at the start of a string," "alphanumeric value or numeric value", 0}, { 20011, "string missing closing double-quote character", 0}, { 20012, "numeric value starts with a decimal point", 0}, { 20013, "numeric value does not contain any digits", 0}, { 20014, "no alphanumeric value after command modifier", 0}, { 20015, "option name and equal sign encountered" " but value field is missing", 0}, { 20016, "more than one command modifier", 0}, { 20017, "command modifier encountered after an option", 0}, { 20018, "command not an alphanumeric value", 0}, { 20019, "numeric value encountered when" " an alphanumeric value expected", 0}, { 20020, "string encountered when an alphanumeric value expected", 0}, { 20021, "unsupported command modifier", 0}, { 20022, "command modifier missing", 0}, { 20023, "option missing", 0}, { 20024, "extra data received after option name", 0}, { 20025, "two decimal points in a numeric value", 0}, { 20026, "invalid binary value", 0}, /* PJL Parser Warning */ { 25001, "generic warning", 0}, { 25002, "PJL prefix missing", 0}, { 25003, "alphanumeric value too long", 0}, { 25004, "string too long", 0}, { 25005, "numeric value too long", 0}, { 25006, "unsupported option name", 0}, { 25007, "option name requires a value which is missing", 0}, { 25008, "option name requires value of a different type", 0}, { 25009, "option name received with a value," " but this option does not support values", 0}, { 25010, "same option name received more than once", 0}, { 25011, "ignored option name due to value underflow or overflow", 0}, { 25012, "value truncated or rounded", 0}, { 25013, "value out of range; used closest supported limit", 0}, { 25014, "value out of range; ignored", 0}, { 25016, "option name received with an alphanumeric value," " but this value is not supported", 0}, { 25017, "string empty, option ignored", 0}, /* PJL Semantic Errors; */ { 27001, "generic sematic error", 0}, { 27002, "EOJ encountered without a previous matching JOB command", 0}, { 27004, "value of a read-only variable can not be changed", 0}, /* Auto-Continuable Condition */ { 30010, "status buffer overflow", 0}, { 30016, "memory overflow", 0}, { 30017, "print overrun", 0}, { 30018, "communication error", 0}, { 30027, "IO buffer overflow", 0}, { 30034, "paper feed error", 0}, { 30035, "NVRAM error", 0}, { 30036, "NVRAM full", 0}, { 30072, "Remove Page", 0}, { 30076, "Personity Memory Overflow", 0}, { 30094, "General Misprint Error", 0}, { 30095, "41.2 Beam Detect Malfunction", 0}, { 30096, "41.3 Improper or unexpected paper size", 0}, { 30097, "41.4 No video sync", 0}, { 30098, "41.4 Noisy video sync", 0}, { 30099, "Invalid input source", 0}, { 30100, "Invalid output destination", 0}, { 30101, "Binding agent out of supplies", 0}, { 30102, "Binding agent misalignment", 0}, { 30103, "Binding agent media capacity exceeded", 0}, { 30104, "External input paper path jam", 0}, { 30105, "External output paper path jam", 0}, { 30106, "External input device error", 0}, { 30107, "External output device error", 0}, { 30108, "MIO Error, press GO key", 0}, { 30109, "Bad serial data format, press GO key", 0}, { 30110, "MIO Error, press GO key", 0}, { 30111, "Parallel IO Error, press GO key", 0}, { 30112, "Serial IO Error, press GO key", 0}, { 30113, "Stopping check last page", 0}, { 30114, "Press select to cancel job", 0}, { 30119, "Media Feed error", 0}, /* Possible Operator Intervention Condition */ { 35029, "BAD MIO", 0}, { 35029, "W1 image adapt", 0}, { 35030, "WA job altered", 0}, { 35031, "W2 invalid personality", 0}, { 35032, "WL warnings lost", 0}, { 35037, "W3 job aborted", 0}, { 35039, "W9 job 600/LTR", 0}, { 35040, "W0 job 600/A4", 0}, { 35041, "W8 job 600/OFF", 0}, { 35042, "W7 job 300/LGL", 0}, { 35043, "W5 job 300/LTR", 0}, { 35044, "W6 job 300/A4", 0}, { 35045, "W4 job 300/OFF", 0}, /* turn off from control panel using SERVICE MSG = NO */ { 35073, "WM Chk MEM Config", 0}, { 35074, "WM MEM Config N/A", 0}, { 35075, "User Maintenance Required (200000 copies done)", 0}, { 35076, "WM Memory Full, stored data lost", 0}, { 35078, "powersave mode", 0}, { 35081, "WM Job 300", 0}, { 35082, "WD Disk not init", 0}, { 35084, "WM job 600/LGL", 0}, { 35085, "WM job 600/A3", 0}, { 35086, "WM job 600/11x17", 0}, { 35087, "WM job 600/A3", 0}, { 35088, "WM job 600/11x17", 0}, { 35115, "Volume 1 not init", 0}, { 35117, "Volume 2 not init", 0}, /* Operator Intervention Needed */ { 40000, "Sleep Mode (STANDBY)", 0}, { 40005, "Cartridge Error or Reading Setup Sheet", 0}, { 40010, "no EP cartridge", 0}, { 40011, "Error Accessing ink cartridge", 0}, { 40019, "upper out-bin full", 0}, { 40021, "printer open", 0}, { 40022, "paper jam", 0}, { 40024, "FE cartridge", 0}, { 40026, "PC install", 0}, { 40038, "toner low", 0}, { 40046, "insert cartridge", 0}, { 40047, "remove cartridge", 0}, { 40048, "[PJL OpMsg]", 0}, { 40049, "[PJL StMsg]", 0}, { 40050, "service error 50", 0}, { 40051, "temporary error 51", 0}, { 40052, "temporary error 52", 0}, { 40053, "memory error", 0}, { 40054, "54 error", 0}, { 40055, "temporary error 55", 0}, { 40056, "56 Error", 0}, { 40057, "service error 57", 0}, { 40058, "service error 58", 0}, { 40059, "59 error", 0}, { 40061, "RAM parity error", 0}, { 40062, "error during memory check", 0}, { 40063, "internal RAM error", 0}, { 40064, "internal service error 64", 0}, { 40065, "65 error", 0}, { 40067, "67 error", 0}, { 40069, "70 error", 0}, { 40070, "71 error", 0}, { 40071, "72 error", 0}, { 40079, "offline", 0}, { 40080, "EE incompatible", 0}, { 40083, "FS Disk Failure", 0}, { 40089, "Incomplete Tray3 Installed", 0}, { 40090, "Incomplete Envelope Feeder Installed", 0}, { 40092, "81 service", 0}, { 40093, "Duplexer Jam", 0}, { 40099, "56.1 Error Press Select Key", 0}, { 40100, "56.2 Error Press Select Key", 0}, { 40102, "Finisher alignment error", 0}, { 40103, "Finisher limit reached", 0}, { 40104, "Input device feed path open", 0}, { 40105, "Output device delivery path open", 0}, { 40106, "Input operation error", 0}, { 40107, "Ouput operation error", 0}, { 40116, "Volume 1 failure", 0}, { 40118, "Volume 2 failure", 0}, { 40120, "Open face-up output bin", 0}, { 40121, "Close face-up output bin", 0}, { 40122, "Duplexer not installed", 0}, { 40123, "Duplexer error, remove duplexer", 0}, { 40124, "Bad Duplexer connection", 0}, { 0, 0, 0}, }; static code_t tray_status[] = { { 1, "Tray Open", 0}, { 2, "Tray Lifting", 0}, { 0, 0, 0} }; static code_t bin_status[] = { { 1, "Output Bin Full", 0}, { 2, "Output Bin Open", 0}, { 3, "Output Bin Broken", 0}, { 0, 0, 0} }; static code_t tray_tab[] = { { 0, "MP/Tray1/DuplexTray", 0}, { 1, "Manual Feed", 0}, { 2, "PC/Upper/Tray2", 0}, { 3, "LC/Lower/Tray3", 0}, { 4, "EE/EnvelopeFeeder", 0}, { 5, "HCI", 0}, { 0, 0, 0}, }; static code_t media_tab[] = { { 0, "Unknown Paper", 0}, { 1, "Unknown envelope", 0}, { 2, "Letter Paper", 0}, { 3, "Legal Paper", 0}, { 4, "A4 Paper", 0}, { 5, "Exec Paper", 0}, { 6, "Ledger Paper", 0}, { 7, "A3 Paper", 0}, { 8, "COM10 envelope", 0}, { 9, "Monarch envelope", 0}, { 10, "C5 envelope", 0}, { 11, "DL envelope", 0}, { 12, "B4 Paper", 0}, { 13, "B5 Paper", 0}, { 14, "B5 envelope", 0}, { 15, "Custom media", 0}, { 16, "J-Postcard", 0}, { 17, "J-RoundTrip Postcard", 0}, { 18, "A5 Paper", 0}, { 19, "Letter-R Paper", 0}, { 20, "A4-R Paper", 0}, { 21, "A5-R Paper", 0}, { 22, "Japan B5-R Paper", 0}, { 23, "Exec-R Paper", 0}, { 24, "A6 Paper", 0}, { 25, "Foolscap Paper", 0}, { 26, "Japan B6 Paper", 0}, { 0, 0, 0}, }; static code_t jam_location[] = { { 0, "Non-specific jam", 0}, { 1, "Paper feed 1 jam", 0}, { 2, "Paper feed 2 jam", 0}, { 3, "Fuser output jam", 0}, { 4, "Fuser output jam", 0}, { 5, "Face down output jam", 0}, { 6, "Face down output jam", 0}, { 7, "2 Sided Turn Around jam", 0}, { 8, "2 Sided Turn Around jam", 0}, { 9, "2 Sided path jam", 0}, { 10, "2 Sided path jam", 0}, { 11, "External input device jam", 0}, { 12, "External output device jam", 0}, { 13, "Fuser Accordion jam", 0}, { 14, "Fuser Accordion jam", 0}, { 15, "Printer could not eject paper jam", 0}, { 0, 0, 0 }, }; static code_t ext_dev[] = { { 1, "Device 1", 0}, { 2, "Device 2", 0}, { 3, "Device 3", 0}, { 4, "Device 4", 0}, { 5, "Device 5", 0}, { 0, 0, 0}, }; static code_t ext_code[] = { { 1, "Unable to communicate with PHC", 0}, { 2, "Out of sequence packet", 0}, { 3, "Bad Transaction", 0}, { 4, "Invalid status bits", 0}, { 5, "Invalid status code", 0}, { 6, "Invalid device specified", 0}, { 7, "Invalid tray specified", 0}, { 8, "Invalid bin specified", 0}, { 9, "Invalid number of special purpose bytes", 0}, { 10, "Invalid number of NVEE bytes", 0}, { 11, "General PHC malfunction", 0}, { 12, "Bad PHC RAM", 0}, { 13, "PHC ROM Checksum Error", 0}, { 14, "Faulty PHC FIFO", 0}, { 15, "PHC cannot communicate with devices", 0}, { 16, "PHC never ready", 0}, { 17, "FIFO empty when expecting data", 0}, { 18, "FIFO full when tray to send data", 0}, { 19, "Invalid page ACK", 0}, { 20, "Pack ACK timeout", 0}, { 21, "Inconsistent page size", 0}, { 22, "Wrong page ack", 0}, { 23, "Devices never ready during initialization", 0}, { 24, "Negative ACK of ready tray", 0}, { 0, 0, 0 }, }; static code_t lj4000_jam[] = { { 0, "Unknown jam", 0}, { 1, "input area jam", 0}, { 2, "output area jam", 0}, { 3, "underneath top cover jam", 0}, { 4, "duplexer jam", 0}, { 5, "duplex front cover area jam", 0}, { 6, "face down output area jam", 0}, { 7, "front door area jam", 0}, { 8, "left door area jam", 0}, { 9, "right door area jam", 0}, { 0, 0, 0}, }; static code_t * lookup(code_t *tab, int target) { DEBUG4("lookup_code: code %d", target ); while( tab->msg && tab->code != target ) ++tab; DEBUG4("lookup_code: return %d '%s'", tab->code, tab->msg ); return( tab ); } void pjl_message(char *code_str, char *msg, int msglen) { code_t *code_group, *decoded_msg, *tray, *media, *status; int code = atoi(code_str); int group = PJLC_GROUP(code); int X, XX, Y, YY; X = PJLC_X(code); YY = PJLC_YY(code); XX = PJLC_XX(code); Y = PJLC_Y(code); DEBUG4("pjl_message: code %d, group %d, X %d, YY %d, XX %d, Y %d", code, group, X, YY, XX, Y ); /* find the code group name */ msg[0] = 0; decoded_msg = lookup(pjlmsg, code ); if( decoded_msg->msg ){ SNPRINTF(msg,msglen) "%s",decoded_msg->msg); return; } /* now we use the code group name */ code_group = lookup( groupcode, group ); switch( code_group->flag ){ /* 11 XTrayCodeYYMediaCode tray_tab media_tab */ case XTrayCodeYYMediaCode: tray = lookup( tray_tab, X ); media = lookup( media_tab, YY ); SNPRINTF(msg,msglen) "%s - %s", tray->msg, media->msg ); break; /* 12 XTrayCodeYYTrayStatus tray_tab tray_status */ case XTrayCodeYYTrayStatus: tray = lookup( tray_tab, X ); status = lookup( tray_status, YY ); SNPRINTF(msg,msglen) "%s - %s", tray->msg, status->msg ); break; /* 15 XXOutputYBinStatus binnumber bin_status */ case XXOutputYBinStatus: status = lookup( bin_status, Y ); SNPRINTF(msg,msglen) "Bin %d - %s", XX, status->msg ); break; /* 42 XJamCountYYJamLocation jamcount jam_location */ case XJamCountYYJamLocation: status = lookup( jam_location, YY ); SNPRINTF(msg,msglen) "%s - %d pages", status->msg, X ); break; /* 43 XExtDeviceYYCode ext_dev ext_code */ case XExtDeviceYYCode: tray = lookup( ext_dev, X ); status = lookup( ext_code, YY ); SNPRINTF(msg,msglen) "%s - %s", tray->msg, status->msg ); break; /* 44 XJamCountYY4000Location jamcount lj4000_jam */ case XJamCountYY4000Location: status = lookup( lj4000_jam, YY ); SNPRINTF(msg,msglen) "%s - %d pages", status->msg, X ); break; } if( msg[0] == 0 ){ if( code_group->msg ){ SNPRINTF(msg,msglen) "%s - message '%s'", code_group->msg, code_str ); } else { SNPRINTF(msg,msglen) "Unknown message '%s'", code_str ); } } } void Check_code( char *code_str, char *msg, int msglen ) { char *s; DEBUG4( "Check_code: '%s'", code_str ); msg[0] = 0; pjl_message( code_str, msg, msglen ); if( msg[0] == 0 && (s = GET_HASH_STR_OBJ(Pjl_error_codes, code_str, MEMINFO)) ){ SNPRINTF(msg,msglen) "%s", s ); } DEBUG4("Check_code: returning '%s'", msg ); }