1 /*****************************************************************************\
3 ptest.c - HP MFP photo card file manager
5 (c) 2004 Copyright Hewlett-Packard Development Company, LP
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 \*****************************************************************************/
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
27 #include <netinet/in.h>
37 #include <arpa/inet.h>
44 #define EXCEPTION_TIMEOUT 45 /* seconds */
45 #define DEV_ACK 0x0100
50 unsigned short nsector;
51 } __attribute__((packed)) CMD_READ_REQUEST;
55 unsigned short nsector;
56 short cs; /* check sum is not used */
57 } __attribute__((packed)) CMD_WRITE_REQUEST;
64 } __attribute__((packed)) RESPONSE_SECTOR;
66 static int hd=-1, channel=-1;
70 int bug(const char *fmt, ...)
78 if ((n = vsnprintf(buf, 256, fmt, args)) == -1)
79 buf[255] = 0; /* output was truncated */
81 fprintf(stderr, "%s", buf);
82 syslog(LOG_WARNING, "%s", buf);
89 int last_slash(const char *path, int *number_found, int *path_size)
91 int i, found=0, lasti=0;
94 for (i=0; path[i] && i<HPMUD_LINE_SIZE; i++)
101 *number_found = found;
107 int nth_slash(const char *path, int n)
109 int i, found=0, lasti=0;
112 for (i=0; path[i] && i<HPMUD_LINE_SIZE; i++)
124 char *basename(const char *path)
126 int len, found=0, slash_index=0;
128 slash_index = last_slash(path, &found, &len);
129 return found ? (char *)path+slash_index+1 : (char *)path;
132 int dirname(const char *path, char *dir)
134 int len, found=0, slash_index=0;
136 slash_index = last_slash(path, &found, &len);
139 strcpy(dir, "."); /* no '/' */
140 else if (path[slash_index+1]==0 && found==1)
141 strcpy(dir, "/"); /* '/' only */
142 else if (path[slash_index+1]==0 && found>1)
144 slash_index = nth_slash(path, found-1); /* trailing '/', backup */
145 strncpy(dir, path, slash_index);
150 strncpy(dir, path, slash_index); /* normal '/' */
153 return slash_index; /* return length of dir */
156 int GetDir(char *path, char *dir, char **tail)
164 strcpy(dir, "."); /* end of path */
167 else if ((path[0] == '/') && (*tail != path))
169 strcpy(dir, "/"); /* found root '/' at beginning of path */
174 for (i=0; path[i] && (path[i] != '/') && (i<HPMUD_LINE_SIZE); i++) /* copy directory entry */
177 strcpy(dir, "."); /* end of path */
181 i++; /* bump past '/' */
185 *tail = path + i; /* tail points to next directory or 0 */
190 int get_uri(char *uri, int urisize)
192 char buf[HPMUD_LINE_SIZE*64];
193 int i=0, cnt, bytes_read;
198 hpmud_probe_devices(HPMUD_BUS_USB, buf, sizeof(buf), &cnt, &bytes_read);
200 /* Return first uri in list. */
203 pBeg = strstr(buf, "hp:");
204 for (i=0; *pBeg != ' ' && (i < urisize); i++, pBeg++) /* copy uri */
206 uri[i] = 0; /* zero terminate */
212 int ReadSector(int sector, int nsector, void *buf, int size)
214 char message[HPMUD_BUFFER_SIZE];
215 int i, len, rlen, wlen, stat=1, total=0;
216 CMD_READ_REQUEST *pC;
219 short cmd=0x0010; /* read request */
221 if (nsector <= 0 || (nsector*FAT_HARDSECT) > size)
223 bug("ReadSector invalid sector count=%d\n", nsector);
227 /* Write photo card command to device. */
228 pC = (CMD_READ_REQUEST *)message;
229 pC->cmd = htons(cmd);
230 pC->nsector = htons(nsector);
231 pSect = (uint32_t *)(message + sizeof(CMD_READ_REQUEST));
232 for (i=0; i<nsector; i++)
233 *pSect++ = htonl(sector+i);
234 wlen = sizeof(CMD_READ_REQUEST)+(4*nsector);
235 hpmud_write_channel(hd, channel, message, wlen, EXCEPTION_TIMEOUT, &len);
237 /* Read photo card response header from device. */
238 memset(message, 0, sizeof(RESPONSE_SECTOR));
239 rlen = sizeof(RESPONSE_SECTOR);
240 hpmud_read_channel(hd, channel, message, rlen, EXCEPTION_TIMEOUT, &len);
241 pR = (RESPONSE_SECTOR *)message;
242 if (ntohs(pR->cmd) != (cmd | DEV_ACK))
244 bug("ReadSector invalid response header cmd=%x expected=%x\n", ntohs(pR->cmd), cmd | DEV_ACK);
252 fprintf(stderr, "photo card firmware version=%x\n", ntohs(pR->ver));
255 /* Read photo card sector data from device. */
256 rlen = nsector*FAT_HARDSECT;
259 hpmud_read_channel(hd, channel, buf+total, rlen, EXCEPTION_TIMEOUT, &len);
267 bug("ReadSector invalid response data len=%d expected=%d\n", total, rlen);
277 int WriteSector(int sector, int nsector, void *buf, int size)
279 char message[HPMUD_BUFFER_SIZE];
280 int i, len, wlen, stat=1;
281 CMD_WRITE_REQUEST *pC;
283 short response=0, cmd=0x0020; /* write request */
285 if (nsector <= 0 || (nsector*FAT_HARDSECT) > size)
287 bug("WriteSector invalid sector count=%d\n", nsector);
291 /* Write photo card command header to device. */
292 pC = (CMD_WRITE_REQUEST *)message;
293 pC->cmd = htons(cmd);
294 pC->nsector = htons(nsector);
296 pSect = (uint32_t *)(message + sizeof(CMD_WRITE_REQUEST));
297 for (i=0; i<nsector; i++)
298 *pSect++ = htonl(sector+i);
299 wlen = sizeof(CMD_WRITE_REQUEST)+(4*nsector);
300 hpmud_write_channel(hd, channel, message, wlen, EXCEPTION_TIMEOUT, &len);
302 /* Write photo card sector data to device. */
303 hpmud_write_channel(hd, channel, buf, size, EXCEPTION_TIMEOUT, &len);
306 hpmud_read_channel(hd, channel, &response, sizeof(response), EXCEPTION_TIMEOUT, &len);
307 if (ntohs(response) != DEV_ACK)
309 bug("WriteSector invalid response cmd=%x expected=%x\n", ntohs(response), DEV_ACK);
320 fprintf(stdout, "HP MFP Photo Card File Manager %s\n", VERSION);
321 fprintf(stdout, "(c) 2004-2007 Copyright Hewlett-Packard Development Company, LP\n");
322 fprintf(stdout, "usage: ptest [-v] [-u uri] -c ls [-p path] (list directory)\n");
323 fprintf(stdout, " ptest [-v] [-u uri] -c read -p path (read file to stdout)\n");
324 fprintf(stdout, " ptest [-v] [-u uri] -c rm -p path (delete file)\n");
325 // fprintf(stdout, " ptest [-v] -u uri -c write -p path (write stdin to file)\n");
328 int main(int argc, char *argv[])
330 char cmd[16] = "", path[HPMUD_LINE_SIZE]="", uri[HPMUD_LINE_SIZE]="", dir[HPMUD_LINE_SIZE]="", spath[HPMUD_LINE_SIZE]="";
334 PHOTO_CARD_ATTRIBUTES pa;
335 struct hpmud_model_attributes ma;
337 while ((i = getopt(argc, argv, "vhu:c:p:")) != -1)
342 strncpy(cmd, optarg, sizeof(cmd));
345 strncpy(path, optarg, sizeof(path));
348 strncpy(uri, optarg, sizeof(uri));
358 fprintf(stderr, "unknown argument: %s\n", argv[1]);
366 get_uri(uri, sizeof(uri));
369 bug("no uri found\n");
373 /* Get any parameters needed for DeviceOpen. */
374 hpmud_query_model(uri, &ma);
376 if (hpmud_open_device(uri, ma.mfp_mode, &hd) != HPMUD_R_OK)
378 bug("unable to open device %s\n", uri);
381 if (hpmud_open_channel(hd, "HP-CARD-ACCESS", &channel) != HPMUD_R_OK)
383 bug("unable to open hp-card-access channel %s\n", uri);
389 bug("unable to read photo card %s\n", uri);
393 FatDiskAttributes(&pa);
395 /* If disk is write protected reopen channel to clear write error. */
398 hpmud_close_channel(hd, channel);
399 if (hpmud_open_channel(hd, "HP-CARD-ACCESS", &channel) != HPMUD_R_OK)
401 bug("unable to open hp-card-access channel %s\n", uri);
406 if (strcasecmp(cmd, "ls") == 0)
408 /* Walk the path for each directory entry. */
409 GetDir(path, dir, &tail);
413 GetDir(tail, dir, &tail);
418 else if (strcasecmp(cmd, "read") == 0)
420 dirname(path, spath); /* extract directory */
421 GetDir(spath, dir, &tail);
425 GetDir(tail, dir, &tail);
428 if ((FatReadFile(basename(path), STDOUT_FILENO)) <= 0)
430 bug("unable to locate file %s\n", path);
434 else if (strcasecmp(cmd, "rm") == 0)
436 dirname(path, spath); /* extract directory */
437 GetDir(spath, dir, &tail);
441 GetDir(tail, dir, &tail);
444 if (FatDeleteFile(basename(path)) != 0)
446 bug("unable to locate file %s\n", path);
452 usage(); /* invalid command */
460 hpmud_close_channel(hd, channel);
462 hpmud_close_device(hd);