1 /*****************************************************************************\
2
3 hpmud.cpp - multi-point transport driver
4
5 (c) 2004-2007 Copyright HP Development Company, LP
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 of the Software, and to permit persons to whom the Software is furnished to do
12 so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 Author: Naga Samrat Chowdary Narla,
25 Contributor: Sarbeswar Meher
26 \*****************************************************************************/
27
28 #include "hpmud.h"
29 #include "hpmudi.h"
30
31 /* Client data. */
32 mud_session ms __attribute__ ((visibility ("hidden"))); /* mud session, one per client */
33 mud_session *msp __attribute__ ((visibility ("hidden"))) = &ms;
34
35 /*
36 * sysdump() originally came from http://sws.dett.de/mini/hexdump-c , steffen@dett.de .
37 */
sysdump(const void * data,int size)38 void __attribute__ ((visibility ("hidden"))) sysdump(const void *data, int size)
39 {
40 /* Dump size bytes of *data. Output looks like:
41 * [0000] 75 6E 6B 6E 6F 77 6E 20 30 FF 00 00 00 00 39 00 unknown 0.....9.
42 */
43
44 unsigned char *p = (unsigned char *)data;
45 unsigned char c;
46 int n;
47 char bytestr[4] = {0};
48 char addrstr[10] = {0};
49 char hexstr[16*3 + 5] = {0};
50 char charstr[16*1 + 5] = {0};
51 for(n=1;n<=size;n++) {
52 if (n%16 == 1) {
53 /* store address for this line */
54 snprintf(addrstr, sizeof(addrstr), "%.4d", (int)((p-(unsigned char *)data) & 0xffff));
55 }
56
57 c = *p;
58 if (isprint(c) == 0) {
59 c = '.';
60 }
61
62 /* store hex str (for left side) */
63 snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
64 strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
65
66 /* store char str (for right side) */
67 snprintf(bytestr, sizeof(bytestr), "%c", c);
68 strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
69
70 if(n%16 == 0) {
71 /* line completed */
72 DBG_SZ("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
73 hexstr[0] = 0;
74 charstr[0] = 0;
75 }
76 p++; /* next byte */
77 }
78
79 if (strlen(hexstr) > 0) {
80 /* print rest of buffer if not empty */
81 DBG_SZ("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
82 }
83 }
84
85 /* Given the IEEE 1284 device id string, determine if this is a HP product. */
is_hp(const char * id)86 int __attribute__ ((visibility ("hidden"))) is_hp(const char *id)
87 {
88 char *pMf;
89 if (id == 0 || id[0] == 0)
90 return 0;
91
92 if ((pMf = strstr(id, "MFG:")) != NULL)
93 pMf+=4;
94 else if ((pMf = strstr(id, "MANUFACTURER:")) != NULL)
95 pMf+=13;
96 else
97 return 0;
98
99 if ((strncasecmp(pMf, "HEWLETT-PACKARD", 15) == 0) ||
100 (strncasecmp(pMf, "APOLLO", 6) == 0) || (strncasecmp(pMf, "HP", 2) == 0))
101 {
102 return 1; /* found HP product */
103 }
104 return 0;
105 }
106
generalize_model(const char * sz,char * buf,int bufSize)107 int __attribute__ ((visibility ("hidden"))) generalize_model(const char *sz, char *buf, int bufSize)
108 {
109 const char *pMd=sz;
110 int i, j, dd=0;
111
112 if (sz == 0 || sz[0] == 0)
113 return 0;
114
115
116 for (i=0; pMd[i] == ' ' && i < bufSize; i++); /* eat leading white space */
117
118 for (j=0; (pMd[i] != 0) && (pMd[i] != ';') && (j < bufSize); i++)
119 {
120 if (pMd[i]==' ' || pMd[i]=='/')
121 {
122 /* Remove double spaces. */
123 if (!dd)
124 {
125 buf[j++] = '_'; /* convert space to "_" */
126 dd=1;
127 }
128 }
129 else
130 {
131 buf[j++] = pMd[i];
132 dd=0;
133 }
134 }
135
136 for (j--; buf[j] == '_' && j > 0; j--); /* eat trailing white space */
137
138 buf[++j] = 0;
139
140 return j; /* length does not include zero termination */
141 }
142
generalize_serial(const char * sz,char * buf,int bufSize)143 int __attribute__ ((visibility ("hidden"))) generalize_serial(const char *sz, char *buf, int bufSize)
144 {
145 const char *pMd=sz;
146 int i, j;
147
148 if (sz == 0 || sz[0] == 0)
149 return 0;
150
151 for (i=0; pMd[i] == ' ' && i < bufSize; i++); /* eat leading white space */
152
153 for (j=0; (pMd[i] != 0) && (i < bufSize); i++)
154 {
155 buf[j++] = pMd[i];
156 }
157
158 for (i--; buf[i] == ' ' && i > 0; i--); /* eat trailing white space */
159
160 buf[++i] = 0;
161
162 return i; /* length does not include zero termination */
163 }
164
165 /* Parse serial number from uri string. */
get_uri_serial(const char * uri,char * buf,int bufSize)166 int __attribute__ ((visibility ("hidden"))) get_uri_serial(const char *uri, char *buf, int bufSize)
167 {
168 char *p;
169 int i;
170
171 if (uri == 0 || uri[0] == 0)
172 return 0;
173
174 buf[0] = 0;
175
176 if ((p = strcasestr(uri, "serial=")) != NULL)
177 p+=7;
178 else
179 return 0;
180
181 for (i=0; (p[i] != 0) && (p[i] != '+') && (i < bufSize); i++)
182 buf[i] = p[i];
183
184 buf[i] = 0;
185
186 return i;
187 }
188
service_to_channel(mud_device * pd,const char * sn,HPMUD_CHANNEL * index)189 enum HPMUD_RESULT __attribute__ ((visibility ("hidden"))) service_to_channel(mud_device *pd, const char *sn, HPMUD_CHANNEL *index)
190 {
191 enum HPMUD_RESULT stat;
192
193 *index=-1;
194
195 /* Check for valid service requests. */
196 if (strncasecmp(sn, "print", 5) == 0)
197 {
198 *index = HPMUD_PRINT_CHANNEL;
199 }
200 else if (strncasecmp(sn, "hp-ews-ledm", 11) == 0)
201 {
202 *index = HPMUD_EWS_LEDM_CHANNEL;
203 }
204 else if (strncasecmp(sn, "hp-ews", 6) == 0)
205 {
206 *index = HPMUD_EWS_CHANNEL;
207 }
208 else if (strncasecmp(sn, "hp-soap-scan", 12) == 0)
209 {
210 *index = HPMUD_SOAPSCAN_CHANNEL;
211 }
212 else if (strncasecmp(sn, "hp-soap-fax", 11) == 0)
213 {
214 *index = HPMUD_SOAPFAX_CHANNEL;
215 }
216 else if (strncasecmp(sn, "hp-marvell-scan", 15) == 0)
217 {
218 *index = HPMUD_MARVELL_SCAN_CHANNEL;
219 }
220 else if (strncasecmp(sn, "hp-marvell-fax", 14) == 0)
221 {
222 *index = HPMUD_MARVELL_FAX_CHANNEL;
223 }
224 else if (strncasecmp(sn, "hp-ledm-scan", 12) == 0)
225 {
226 *index = HPMUD_LEDM_SCAN_CHANNEL;
227 }
228 else if (strncasecmp(sn, "hp-marvell-ews", 11) == 0)
229 {
230 *index = HPMUD_MARVELL_EWS_CHANNEL;
231 }
232 else if (strncasecmp(sn, "hp-ipp", 6) == 0)
233 {
234 if (strncasecmp(sn, "hp-ipp2", 7) == 0)
235 *index = HPMUD_IPP_CHANNEL2;
236 else
237 *index = HPMUD_IPP_CHANNEL;
238 }
239 else if (strncasecmp(sn, "hp-escl-scan", 12) == 0)
240 {
241 *index = HPMUD_ESCL_SCAN_CHANNEL;
242 }
243 /* All the following services require MLC/1284.4. */
244 else if (pd->io_mode == HPMUD_RAW_MODE || pd->io_mode == HPMUD_UNI_MODE)
245 {
246 BUG("invalid channel_open state, current io_mode=raw/uni service=%s %s\n", sn, pd->uri);
247 stat = HPMUD_R_INVALID_STATE;
248 goto bugout;
249 }
250 else if (strncasecmp(sn, "hp-message", 10) == 0)
251 {
252 *index = HPMUD_PML_CHANNEL;
253 }
254 else if (strncasecmp(sn, "hp-scan", 7) == 0)
255 {
256 *index = HPMUD_SCAN_CHANNEL;
257 }
258 else if (strncasecmp(sn, "hp-fax-send", 11) == 0)
259 {
260 *index = HPMUD_FAX_SEND_CHANNEL;
261 }
262 else if (strncasecmp(sn, "hp-card-access", 14) == 0)
263 {
264 *index = HPMUD_MEMORY_CARD_CHANNEL;
265 }
266 else if (strncasecmp(sn, "hp-configuration-upload", 23) == 0)
267 {
268 *index = HPMUD_CONFIG_UPLOAD_CHANNEL;
269 }
270 else if (strncasecmp(sn, "hp-configuration-download", 25) == 0)
271 {
272 *index = HPMUD_CONFIG_DOWNLOAD_CHANNEL;
273 }
274 else if (strncasecmp(sn, "hp-devmgmt", 10) == 0)
275 {
276 *index = HPMUD_DEVMGMT_CHANNEL;
277 }
278 else if (strncasecmp(sn, "hp-wificonfig", 13) == 0)
279 {
280 *index = HPMUD_WIFI_CHANNEL;
281 }
282 else
283 {
284 BUG("invalid service=%s %s\n", sn, pd->uri);
285 stat = HPMUD_R_INVALID_SN;
286 goto bugout;
287 }
288
289 stat = HPMUD_R_OK;
290
291 bugout:
292 return stat;
293 }
294
295
new_device(const char * uri,enum HPMUD_IO_MODE mode,int * result)296 static int new_device(const char *uri, enum HPMUD_IO_MODE mode, int *result)
297 {
298 int index=0; /* device[0] is unused */
299 int i=1;
300
301 if (uri == 0 || uri[0] == 0)
302 return 0;
303
304 pthread_mutex_lock(&msp->mutex);
305
306 if (msp->device[i].index)
307 {
308 BUG("invalid device_open state\n"); /* device is already open for this client, one device per session */
309 *result = HPMUD_R_INVALID_STATE;
310 goto bugout;
311 }
312
313 index = i; /* currently only support one device per client or process */
314
315 /* Based on uri, set local session attributes. */
316 if (strcasestr(uri, ":/usb") != NULL)
317 {
318 msp->device[i].vf = musb_mud_device_vf;
319 }
320 #ifdef HAVE_LIBNETSNMP
321 else if (strcasestr(uri, ":/net") != NULL)
322 {
323 msp->device[i].vf = jd_mud_device_vf;
324 }
325 #endif
326 #ifdef HAVE_PPORT
327 else if (strcasestr(uri, ":/par") != NULL)
328 {
329 msp->device[i].vf = pp_mud_device_vf;
330 }
331 #endif
332 else
333 {
334 BUG("invalid uri %s\n", uri);
335 *result = HPMUD_R_INVALID_URI;
336 index = 0;
337 goto bugout;
338 }
339 *result = HPMUD_R_OK;
340 msp->device[i].io_mode = mode;
341 msp->device[i].index = index;
342 msp->device[i].channel_cnt = 0;
343 msp->device[i].open_fd = -1;
344 strcpy(msp->device[i].uri, uri);
345
346 bugout:
347 pthread_mutex_unlock(&msp->mutex);
348
349 return index; /* return device index */
350 }
351
del_device(HPMUD_DEVICE index)352 static int del_device(HPMUD_DEVICE index)
353 {
354 pthread_mutex_lock(&msp->mutex);
355
356 msp->device[index].index = 0;
357
358 pthread_mutex_unlock(&msp->mutex);
359
360 return 0;
361 }
362
363 /* Make sure client closed down the device. */
device_cleanup(mud_session * ps)364 int device_cleanup(mud_session *ps)
365 {
366 int i, dd=1;
367
368 if (!ps) return 0;
369
370 if(!ps->device[dd].index)
371 return 0; /* nothing to do */
372
373 BUG("device_cleanup: device uri=%s\n", ps->device[dd].uri);
374
375 for (i=0; i<HPMUD_CHANNEL_MAX; i++)
376 {
377 if (ps->device[dd].channel[i].client_cnt)
378 {
379 BUG("device_cleanup: close channel %d...\n", i);
380 hpmud_close_channel(dd, ps->device[dd].channel[i].index);
381 BUG("device_cleanup: done closing channel %d\n", i);
382 }
383 }
384
385 BUG("device_cleanup: close device dd=%d...\n", dd);
386 hpmud_close_device(dd);
387 BUG("device_cleanup: done closing device dd=%d\n", dd);
388
389 return 0;
390 }
391
mud_init(void)392 static void __attribute__ ((constructor)) mud_init(void)
393 {
394 DBG("[%d] hpmud_init()\n", getpid());
395 }
396
mud_exit(void)397 static void __attribute__ ((destructor)) mud_exit(void)
398 {
399 DBG("[%d] hpmud_exit()\n", getpid());
400 device_cleanup(msp);
401 }
402
403 /*******************************************************************************************************************************
404 * Helper functions.
405 */
406
407 /* Parse the model from the IEEE 1284 device id string and generalize the model name */
hpmud_get_model(const char * id,char * buf,int buf_size)408 int hpmud_get_model(const char *id, char *buf, int buf_size)
409 {
410 char *pMd;
411
412 if (id == 0 || id[0] == 0)
413 return 0;
414
415 buf[0] = 0;
416
417 if ((pMd = strstr(id, "MDL:")) != NULL)
418 pMd+=4;
419 else if ((pMd = strstr(id, "MODEL:")) != NULL)
420 pMd+=6;
421 else
422 return 0;
423
424 return generalize_model(pMd, buf, buf_size);
425 }
426
427 /* Parse the model from the IEEE 1284 device id string. */
hpmud_get_raw_model(char * id,char * raw,int rawSize)428 int hpmud_get_raw_model(char *id, char *raw, int rawSize)
429 {
430 char *pMd;
431 int i;
432
433 if (id == 0 || id[0] == 0)
434 return 0;
435
436 raw[0] = 0;
437
438 if ((pMd = strstr(id, "MDL:")) != NULL)
439 pMd+=4;
440 else if ((pMd = strstr(id, "MODEL:")) != NULL)
441 pMd+=6;
442 else
443 return 0;
444
445 for (i=0; (pMd[i] != ';') && (i < rawSize); i++)
446 raw[i] = pMd[i];
447 raw[i] = 0;
448
449 return i;
450 }
451
452 /* Parse device model from uri string. */
hpmud_get_uri_model(const char * uri,char * buf,int buf_size)453 int hpmud_get_uri_model(const char *uri, char *buf, int buf_size)
454 {
455 char *p;
456 int i;
457
458 if (uri == 0 || uri[0] == 0)
459 return 0;
460
461 buf[0] = 0;
462
463 if ((p = strstr(uri, "/")) == NULL)
464 return 0;
465 if ((p = strstr(p+1, "/")) == NULL)
466 return 0;
467 p++;
468
469 for (i=0; (p[i] != '?') && (i < buf_size); i++)
470 buf[i] = p[i];
471
472 buf[i] = 0;
473
474 return i;
475 }
476
477 /* Parse the data link from a uri string. */
hpmud_get_uri_datalink(const char * uri,char * buf,int buf_size)478 int hpmud_get_uri_datalink(const char *uri, char *buf, int buf_size)
479 {
480 char *p;
481 int i;
482 int zc=0;
483 #ifdef HAVE_LIBNETSNMP
484 char ip[HPMUD_LINE_SIZE];
485 #endif
486
487 if (uri == 0 || uri[0] == 0)
488 return 0;
489
490 buf[0] = 0;
491
492 if ((p = strcasestr(uri, "device=")) != NULL)
493 p+=7;
494 else if ((p = strcasestr(uri, "ip=")) != NULL)
495 p+=3;
496 else if ((p = strcasestr(uri, "hostname=")) != NULL)
497 p+=9;
498 else if ((p = strcasestr(uri, "zc=")) != NULL)
499 {
500 p+=3;
501 zc=1;
502 }
503 else
504 return 0;
505
506 if (zc)
507 {
508 #ifdef HAVE_LIBNETSNMP
509 if (mdns_lookup(p, ip) != MDNS_STATUS_OK)
510 return 0;
511 for (i=0; (ip[i] != 0) && (i < buf_size); i++)
512 buf[i] = ip[i];
513 #else
514 return 0;
515 #endif
516 }
517 else {
518 for (i=0; (p[i] != 0) && (p[i] != '&') && (i < buf_size); i++)
519 buf[i] = p[i];
520 }
521
522 buf[i] = 0;
523
524 return i;
525 }
526
527 /***************************************************************************************************
528 * Core functions.
529 */
530
hpmud_open_device(const char * uri,enum HPMUD_IO_MODE iomode,HPMUD_DEVICE * dd)531 enum HPMUD_RESULT hpmud_open_device(const char *uri, enum HPMUD_IO_MODE iomode, HPMUD_DEVICE *dd)
532 {
533 HPMUD_DEVICE index=0;
534 enum HPMUD_RESULT stat = HPMUD_R_INVALID_URI;
535 int result;
536
537 DBG("[%d,%d,%d,%d,%d,%d] hpmud_device_open() uri=%s iomode=%d\n", getpid(), getppid(), getuid(), geteuid(), getgid(), getegid(), uri, iomode);
538
539 if ((index = new_device(uri, iomode, &result)) == 0)
540 {
541 stat = result;
542 goto bugout;
543 }
544 else
545 {
546 if ((stat = (msp->device[index].vf.open)(&msp->device[index])) != HPMUD_R_OK)
547 {
548 (msp->device[index].vf.close)(&msp->device[index]); /* Open failed perform device cleanup. */
549 del_device(index);
550 goto bugout;
551 }
552 }
553
554 *dd = index;
555 stat = HPMUD_R_OK;
556
557 bugout:
558 return stat;
559 }
560
hpmud_close_device(HPMUD_DEVICE dd)561 enum HPMUD_RESULT hpmud_close_device(HPMUD_DEVICE dd)
562 {
563 enum HPMUD_RESULT stat;
564
565 DBG("[%d] hpmud_device_close() dd=%d\n", getpid(), dd);
566
567 if (dd <= 0 || dd > HPMUD_DEVICE_MAX || msp->device[dd].index != dd)
568 {
569 BUG("invalid device_close state\n");
570 stat = HPMUD_R_INVALID_STATE;
571 }
572 else
573 {
574 stat = (msp->device[dd].vf.close)(&msp->device[dd]);
575 del_device(dd);
576 }
577 return stat;
578 }
579
hpmud_get_device_id(HPMUD_DEVICE dd,char * buf,int size,int * bytes_read)580 enum HPMUD_RESULT hpmud_get_device_id(HPMUD_DEVICE dd, char *buf, int size, int *bytes_read)
581 {
582 enum HPMUD_RESULT stat = HPMUD_R_INVALID_STATE;
583
584 DBG("[%d] hpmud_get_device_id() dd=%d\n", getpid(), dd);
585
586 if (dd <= 0 || dd > HPMUD_DEVICE_MAX || msp->device[dd].index != dd)
587 {
588 BUG("invalid get_device_id state\n");
589 goto bugout;
590 }
591
592 stat = (msp->device[dd].vf.get_device_id)(&msp->device[dd], buf, size, bytes_read);
593
594 bugout:
595 return stat;
596 }
597
hpmud_get_device_status(HPMUD_DEVICE dd,unsigned int * status)598 enum HPMUD_RESULT hpmud_get_device_status(HPMUD_DEVICE dd, unsigned int *status)
599 {
600 enum HPMUD_RESULT stat = HPMUD_R_INVALID_STATE;
601
602 DBG("[%d] hpmud_get_device_status() dd=%d\n", getpid(), dd);
603
604 if (dd <= 0 || dd > HPMUD_DEVICE_MAX || msp->device[dd].index != dd)
605 {
606 BUG("invalid get_device_status state\n");
607 goto bugout;
608 }
609
610 stat = (msp->device[dd].vf.get_device_status)(&msp->device[dd], status);
611
612 bugout:
613 return stat;
614 }
615
hpmud_probe_devices(enum HPMUD_BUS_ID bus,char * buf,int buf_size,int * cnt,int * bytes_read)616 enum HPMUD_RESULT hpmud_probe_devices(enum HPMUD_BUS_ID bus, char *buf, int buf_size, int *cnt, int *bytes_read)
617 {
618 int len=0;
619
620 DBG("[%d] hpmud_probe_devices() bus=%d\n", getpid(), bus);
621 if (buf == NULL || buf_size <= 0)
622 return HPMUD_R_INVALID_LENGTH;
623
624 buf[0] = 0;
625 *cnt = 0;
626
627 if (bus == HPMUD_BUS_USB)
628 {
629 len = musb_probe_devices(buf, buf_size, cnt, HPMUD_AIO);
630 }
631 #ifdef HAVE_PPORT
632 else if (bus == HPMUD_BUS_PARALLEL)
633 {
634 len = pp_probe_devices(buf, buf_size, cnt);
635 }
636 #endif
637 else if (bus == HPMUD_BUS_ALL)
638 {
639 len = musb_probe_devices(buf, buf_size, cnt, HPMUD_AIO);
640 #ifdef HAVE_PPORT
641 len += pp_probe_devices(buf+len, buf_size-len, cnt);
642 #endif
643 }
644
645 *bytes_read = len;
646
647 return HPMUD_R_OK;
648 }
649
hpmud_probe_printers(enum HPMUD_BUS_ID bus,char * buf,int buf_size,int * cnt,int * bytes_read)650 enum HPMUD_RESULT hpmud_probe_printers(enum HPMUD_BUS_ID bus, char *buf, int buf_size, int *cnt, int *bytes_read)
651 {
652 int len=0;
653
654 DBG("[%d] hpmud_probe_printers() bus=%d\n", getpid(), bus);
655
656 if (buf == NULL || buf_size <= 0)
657 return HPMUD_R_INVALID_LENGTH;
658
659 buf[0] = 0;
660 *cnt = 0;
661
662 if (bus == HPMUD_BUS_ALL)
663 {
664 len = musb_probe_devices(buf, buf_size, cnt, HPMUD_PRINTER);
665 #ifdef HAVE_PPORT
666 len += pp_probe_devices(buf+len, buf_size-len, cnt);
667 #endif
668 }
669
670 *bytes_read = len;
671
672 return HPMUD_R_OK;
673 }
674
hpmud_open_channel(HPMUD_DEVICE dd,const char * channel_name,HPMUD_CHANNEL * cd)675 enum HPMUD_RESULT hpmud_open_channel(HPMUD_DEVICE dd, const char *channel_name, HPMUD_CHANNEL *cd)
676 {
677 enum HPMUD_RESULT stat = HPMUD_R_INVALID_STATE;
678
679 DBG("[%d] hpmud_channel_open() dd=%d name=%s\n", getpid(), dd, channel_name);
680
681 if (dd <= 0 || dd > HPMUD_DEVICE_MAX || msp->device[dd].index != dd)
682 {
683 BUG("invalid channel_open state\n");
684 goto bugout;
685 }
686
687 stat = (msp->device[dd].vf.channel_open)(&msp->device[dd], channel_name, cd);
688
689 bugout:
690 return stat;
691 }
692
hpmud_close_channel(HPMUD_DEVICE dd,HPMUD_CHANNEL cd)693 enum HPMUD_RESULT hpmud_close_channel(HPMUD_DEVICE dd, HPMUD_CHANNEL cd)
694 {
695 enum HPMUD_RESULT stat = HPMUD_R_INVALID_STATE;
696
697 DBG("[%d] hpmud_channel_close() dd=%d cd=%d\n", getpid(), dd, cd);
698
699 if (dd <= 0 || dd > HPMUD_DEVICE_MAX || msp->device[dd].index != dd ||
700 cd <=0 || cd > HPMUD_CHANNEL_MAX || msp->device[dd].channel[cd].client_cnt == 0)
701 {
702 BUG("invalid channel_close state\n");
703 goto bugout;
704 }
705
706 stat = (msp->device[dd].vf.channel_close)(&msp->device[dd], &msp->device[dd].channel[cd]);
707
708 bugout:
709 return stat;
710 }
711
hpmud_write_channel(HPMUD_DEVICE dd,HPMUD_CHANNEL cd,const void * buf,int size,int sec_timeout,int * bytes_wrote)712 enum HPMUD_RESULT hpmud_write_channel(HPMUD_DEVICE dd, HPMUD_CHANNEL cd, const void *buf, int size, int sec_timeout, int *bytes_wrote)
713 {
714 enum HPMUD_RESULT stat = HPMUD_R_INVALID_STATE;
715
716 DBG("[%d] hpmud_channel_write() dd=%d cd=%d buf=%p size=%d sectime=%d\n", getpid(), dd, cd, buf, size, sec_timeout);
717
718 if (dd <= 0 || dd > HPMUD_DEVICE_MAX || msp->device[dd].index != dd ||
719 cd <=0 || cd > HPMUD_CHANNEL_MAX || msp->device[dd].channel[cd].client_cnt == 0)
720 {
721 BUG("invalid channel_write state\n");
722 goto bugout;
723 }
724
725 stat = (msp->device[dd].vf.channel_write)(&msp->device[dd], &msp->device[dd].channel[cd], buf, size, sec_timeout, bytes_wrote);
726
727 bugout:
728 return stat;
729 }
730
hpmud_read_channel(HPMUD_DEVICE dd,HPMUD_CHANNEL cd,void * buf,int size,int sec_timeout,int * bytes_read)731 enum HPMUD_RESULT hpmud_read_channel(HPMUD_DEVICE dd, HPMUD_CHANNEL cd, void *buf, int size, int sec_timeout, int *bytes_read)
732 {
733 enum HPMUD_RESULT stat = HPMUD_R_INVALID_STATE;
734 DBG("[%d] hpmud_channel_read() dd=%d cd=%d buf=%p size=%d sectime=%d\n", getpid(), dd, cd, buf, size, sec_timeout);
735
736 if (dd <= 0 || dd > HPMUD_DEVICE_MAX || msp->device[dd].index != dd ||
737 cd <=0 || cd > HPMUD_CHANNEL_MAX || msp->device[dd].channel[cd].client_cnt == 0)
738 {
739 BUG("invalid channel_read state\n");
740 goto bugout;
741 }
742
743 stat = (msp->device[dd].vf.channel_read)(&msp->device[dd], &msp->device[dd].channel[cd], buf, size, sec_timeout, bytes_read);
744
745 bugout:
746 return stat;
747 }
748
hpmud_get_dstat(HPMUD_DEVICE dd,struct hpmud_dstat * ds)749 enum HPMUD_RESULT hpmud_get_dstat(HPMUD_DEVICE dd, struct hpmud_dstat *ds)
750 {
751 enum HPMUD_RESULT stat = HPMUD_R_INVALID_STATE;
752
753 DBG("[%d] hpmud_dstat() dd=%d ds=%p\n", getpid(), dd, ds);
754
755 if (dd <= 0 || dd > HPMUD_DEVICE_MAX)
756 {
757 BUG("invalid dstat state\n");
758 goto bugout;
759 }
760
761 strncpy(ds->uri, msp->device[dd].uri, sizeof(ds->uri));
762 ds->io_mode = msp->device[dd].io_mode;
763 ds->channel_cnt = msp->device[dd].channel_cnt;
764 ds->mlc_up = msp->device[dd].mlc_up;
765
766 stat = HPMUD_R_OK;
767
768 bugout:
769 return stat;
770 }
771