1 /* 2 * LIRC base driver 3 * 4 * by Artur Lipowski <alipowski@interia.pl> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 */ 17 18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19 20 #include <linux/module.h> 21 #include <linux/kernel.h> 22 #include <linux/sched/signal.h> 23 #include <linux/errno.h> 24 #include <linux/ioctl.h> 25 #include <linux/fs.h> 26 #include <linux/poll.h> 27 #include <linux/completion.h> 28 #include <linux/mutex.h> 29 #include <linux/wait.h> 30 #include <linux/unistd.h> 31 #include <linux/kthread.h> 32 #include <linux/bitops.h> 33 #include <linux/device.h> 34 #include <linux/cdev.h> 35 36 #include <media/rc-core.h> 37 #include <media/lirc.h> 38 #include <media/lirc_dev.h> 39 40 static bool debug; 41 42 #define IRCTL_DEV_NAME "BaseRemoteCtl" 43 #define NOPLUG -1 44 #define LOGHEAD "lirc_dev (%s[%d]): " 45 46 static dev_t lirc_base_dev; 47 48 struct irctl { 49 struct lirc_driver d; 50 int attached; 51 int open; 52 53 struct mutex irctl_lock; 54 struct lirc_buffer *buf; 55 unsigned int chunk_size; 56 57 struct cdev *cdev; 58 59 struct task_struct *task; 60 long jiffies_to_wait; 61 }; 62 63 static DEFINE_MUTEX(lirc_dev_lock); 64 65 static struct irctl *irctls[MAX_IRCTL_DEVICES]; 66 67 /* Only used for sysfs but defined to void otherwise */ 68 static struct class *lirc_class; 69 70 /* helper function 71 * initializes the irctl structure 72 */ 73 static void lirc_irctl_init(struct irctl *ir) 74 { 75 mutex_init(&ir->irctl_lock); 76 ir->d.minor = NOPLUG; 77 } 78 79 static void lirc_irctl_cleanup(struct irctl *ir) 80 { 81 device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); 82 83 if (ir->buf != ir->d.rbuf) { 84 lirc_buffer_free(ir->buf); 85 kfree(ir->buf); 86 } 87 ir->buf = NULL; 88 } 89 90 /* helper function 91 * reads key codes from driver and puts them into buffer 92 * returns 0 on success 93 */ 94 static int lirc_add_to_buf(struct irctl *ir) 95 { 96 int res; 97 int got_data = -1; 98 99 if (!ir->d.add_to_buf) 100 return 0; 101 102 /* 103 * service the device as long as it is returning 104 * data and we have space 105 */ 106 do { 107 got_data++; 108 res = ir->d.add_to_buf(ir->d.data, ir->buf); 109 } while (!res); 110 111 if (res == -ENODEV) 112 kthread_stop(ir->task); 113 114 return got_data ? 0 : res; 115 } 116 117 /* main function of the polling thread 118 */ 119 static int lirc_thread(void *irctl) 120 { 121 struct irctl *ir = irctl; 122 123 do { 124 if (ir->open) { 125 if (ir->jiffies_to_wait) { 126 set_current_state(TASK_INTERRUPTIBLE); 127 schedule_timeout(ir->jiffies_to_wait); 128 } 129 if (kthread_should_stop()) 130 break; 131 if (!lirc_add_to_buf(ir)) 132 wake_up_interruptible(&ir->buf->wait_poll); 133 } else { 134 set_current_state(TASK_INTERRUPTIBLE); 135 schedule(); 136 } 137 } while (!kthread_should_stop()); 138 139 return 0; 140 } 141 142 143 static const struct file_operations lirc_dev_fops = { 144 .owner = THIS_MODULE, 145 .read = lirc_dev_fop_read, 146 .write = lirc_dev_fop_write, 147 .poll = lirc_dev_fop_poll, 148 .unlocked_ioctl = lirc_dev_fop_ioctl, 149 .open = lirc_dev_fop_open, 150 .release = lirc_dev_fop_close, 151 .llseek = noop_llseek, 152 }; 153 154 static int lirc_cdev_add(struct irctl *ir) 155 { 156 struct lirc_driver *d = &ir->d; 157 struct cdev *cdev; 158 int retval; 159 160 cdev = cdev_alloc(); 161 if (!cdev) 162 return -ENOMEM; 163 164 if (d->fops) { 165 cdev->ops = d->fops; 166 cdev->owner = d->owner; 167 } else { 168 cdev->ops = &lirc_dev_fops; 169 cdev->owner = THIS_MODULE; 170 } 171 retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); 172 if (retval) 173 goto err_out; 174 175 retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); 176 if (retval) 177 goto err_out; 178 179 ir->cdev = cdev; 180 181 return 0; 182 183 err_out: 184 cdev_del(cdev); 185 return retval; 186 } 187 188 static int lirc_allocate_buffer(struct irctl *ir) 189 { 190 int err = 0; 191 int bytes_in_key; 192 unsigned int chunk_size; 193 unsigned int buffer_size; 194 struct lirc_driver *d = &ir->d; 195 196 mutex_lock(&lirc_dev_lock); 197 198 bytes_in_key = BITS_TO_LONGS(d->code_length) + 199 (d->code_length % 8 ? 1 : 0); 200 buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; 201 chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; 202 203 if (d->rbuf) { 204 ir->buf = d->rbuf; 205 } else { 206 ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); 207 if (!ir->buf) { 208 err = -ENOMEM; 209 goto out; 210 } 211 212 err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); 213 if (err) { 214 kfree(ir->buf); 215 goto out; 216 } 217 } 218 ir->chunk_size = ir->buf->chunk_size; 219 220 out: 221 mutex_unlock(&lirc_dev_lock); 222 223 return err; 224 } 225 226 static int lirc_allocate_driver(struct lirc_driver *d) 227 { 228 struct irctl *ir; 229 int minor; 230 int err; 231 232 if (!d) { 233 pr_err("driver pointer must be not NULL!\n"); 234 return -EBADRQC; 235 } 236 237 if (!d->dev) { 238 pr_err("dev pointer not filled in!\n"); 239 return -EINVAL; 240 } 241 242 if (d->minor >= MAX_IRCTL_DEVICES) { 243 dev_err(d->dev, "minor must be between 0 and %d!\n", 244 MAX_IRCTL_DEVICES - 1); 245 return -EBADRQC; 246 } 247 248 if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) { 249 dev_err(d->dev, "code length must be less than %d bits\n", 250 BUFLEN * 8); 251 return -EBADRQC; 252 } 253 254 if (d->sample_rate) { 255 if (2 > d->sample_rate || HZ < d->sample_rate) { 256 dev_err(d->dev, "invalid %d sample rate\n", 257 d->sample_rate); 258 return -EBADRQC; 259 } 260 if (!d->add_to_buf) { 261 dev_err(d->dev, "add_to_buf not set\n"); 262 return -EBADRQC; 263 } 264 } else if (!d->rbuf && !(d->fops && d->fops->read && 265 d->fops->poll && d->fops->unlocked_ioctl)) { 266 dev_err(d->dev, "undefined read, poll, ioctl\n"); 267 return -EBADRQC; 268 } 269 270 mutex_lock(&lirc_dev_lock); 271 272 minor = d->minor; 273 274 if (minor < 0) { 275 /* find first free slot for driver */ 276 for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) 277 if (!irctls[minor]) 278 break; 279 if (minor == MAX_IRCTL_DEVICES) { 280 dev_err(d->dev, "no free slots for drivers!\n"); 281 err = -ENOMEM; 282 goto out_lock; 283 } 284 } else if (irctls[minor]) { 285 dev_err(d->dev, "minor (%d) just registered!\n", minor); 286 err = -EBUSY; 287 goto out_lock; 288 } 289 290 ir = kzalloc(sizeof(struct irctl), GFP_KERNEL); 291 if (!ir) { 292 err = -ENOMEM; 293 goto out_lock; 294 } 295 lirc_irctl_init(ir); 296 irctls[minor] = ir; 297 d->minor = minor; 298 299 /* some safety check 8-) */ 300 d->name[sizeof(d->name)-1] = '\0'; 301 302 if (d->features == 0) 303 d->features = LIRC_CAN_REC_LIRCCODE; 304 305 ir->d = *d; 306 307 device_create(lirc_class, ir->d.dev, 308 MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, 309 "lirc%u", ir->d.minor); 310 311 if (d->sample_rate) { 312 ir->jiffies_to_wait = HZ / d->sample_rate; 313 314 /* try to fire up polling thread */ 315 ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); 316 if (IS_ERR(ir->task)) { 317 dev_err(d->dev, "cannot run thread for minor = %d\n", 318 d->minor); 319 err = -ECHILD; 320 goto out_sysfs; 321 } 322 } else { 323 /* it means - wait for external event in task queue */ 324 ir->jiffies_to_wait = 0; 325 } 326 327 err = lirc_cdev_add(ir); 328 if (err) 329 goto out_sysfs; 330 331 ir->attached = 1; 332 mutex_unlock(&lirc_dev_lock); 333 334 dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", 335 ir->d.name, ir->d.minor); 336 return minor; 337 338 out_sysfs: 339 device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); 340 out_lock: 341 mutex_unlock(&lirc_dev_lock); 342 343 return err; 344 } 345 346 int lirc_register_driver(struct lirc_driver *d) 347 { 348 int minor, err = 0; 349 350 minor = lirc_allocate_driver(d); 351 if (minor < 0) 352 return minor; 353 354 if (LIRC_CAN_REC(d->features)) { 355 err = lirc_allocate_buffer(irctls[minor]); 356 if (err) 357 lirc_unregister_driver(minor); 358 } 359 360 return err ? err : minor; 361 } 362 EXPORT_SYMBOL(lirc_register_driver); 363 364 int lirc_unregister_driver(int minor) 365 { 366 struct irctl *ir; 367 struct cdev *cdev; 368 369 if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { 370 pr_err("minor (%d) must be between 0 and %d!\n", 371 minor, MAX_IRCTL_DEVICES - 1); 372 return -EBADRQC; 373 } 374 375 ir = irctls[minor]; 376 if (!ir) { 377 pr_err("failed to get irctl\n"); 378 return -ENOENT; 379 } 380 381 cdev = ir->cdev; 382 383 mutex_lock(&lirc_dev_lock); 384 385 if (ir->d.minor != minor) { 386 dev_err(ir->d.dev, "lirc_dev: minor %d device not registered\n", 387 minor); 388 mutex_unlock(&lirc_dev_lock); 389 return -ENOENT; 390 } 391 392 /* end up polling thread */ 393 if (ir->task) 394 kthread_stop(ir->task); 395 396 dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n", 397 ir->d.name, ir->d.minor); 398 399 ir->attached = 0; 400 if (ir->open) { 401 dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n", 402 ir->d.name, ir->d.minor); 403 wake_up_interruptible(&ir->buf->wait_poll); 404 mutex_lock(&ir->irctl_lock); 405 406 if (ir->d.set_use_dec) 407 ir->d.set_use_dec(ir->d.data); 408 409 module_put(cdev->owner); 410 mutex_unlock(&ir->irctl_lock); 411 } else { 412 lirc_irctl_cleanup(ir); 413 cdev_del(cdev); 414 kfree(ir); 415 irctls[minor] = NULL; 416 } 417 418 mutex_unlock(&lirc_dev_lock); 419 420 return 0; 421 } 422 EXPORT_SYMBOL(lirc_unregister_driver); 423 424 int lirc_dev_fop_open(struct inode *inode, struct file *file) 425 { 426 struct irctl *ir; 427 struct cdev *cdev; 428 int retval = 0; 429 430 if (iminor(inode) >= MAX_IRCTL_DEVICES) { 431 pr_err("open result for %d is -ENODEV\n", iminor(inode)); 432 return -ENODEV; 433 } 434 435 if (mutex_lock_interruptible(&lirc_dev_lock)) 436 return -ERESTARTSYS; 437 438 ir = irctls[iminor(inode)]; 439 if (!ir) { 440 retval = -ENODEV; 441 goto error; 442 } 443 444 dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); 445 446 if (ir->d.minor == NOPLUG) { 447 retval = -ENODEV; 448 goto error; 449 } 450 451 if (ir->open) { 452 retval = -EBUSY; 453 goto error; 454 } 455 456 if (ir->d.rdev) { 457 retval = rc_open(ir->d.rdev); 458 if (retval) 459 goto error; 460 } 461 462 cdev = ir->cdev; 463 if (try_module_get(cdev->owner)) { 464 ir->open++; 465 if (ir->d.set_use_inc) 466 retval = ir->d.set_use_inc(ir->d.data); 467 468 if (retval) { 469 module_put(cdev->owner); 470 ir->open--; 471 } else if (ir->buf) { 472 lirc_buffer_clear(ir->buf); 473 } 474 if (ir->task) 475 wake_up_process(ir->task); 476 } 477 478 error: 479 mutex_unlock(&lirc_dev_lock); 480 481 nonseekable_open(inode, file); 482 483 return retval; 484 } 485 EXPORT_SYMBOL(lirc_dev_fop_open); 486 487 int lirc_dev_fop_close(struct inode *inode, struct file *file) 488 { 489 struct irctl *ir = irctls[iminor(inode)]; 490 struct cdev *cdev; 491 int ret; 492 493 if (!ir) { 494 pr_err("called with invalid irctl\n"); 495 return -EINVAL; 496 } 497 498 cdev = ir->cdev; 499 500 ret = mutex_lock_killable(&lirc_dev_lock); 501 WARN_ON(ret); 502 503 rc_close(ir->d.rdev); 504 505 ir->open--; 506 if (ir->attached) { 507 if (ir->d.set_use_dec) 508 ir->d.set_use_dec(ir->d.data); 509 module_put(cdev->owner); 510 } else { 511 lirc_irctl_cleanup(ir); 512 cdev_del(cdev); 513 irctls[ir->d.minor] = NULL; 514 kfree(ir); 515 } 516 517 if (!ret) 518 mutex_unlock(&lirc_dev_lock); 519 520 return 0; 521 } 522 EXPORT_SYMBOL(lirc_dev_fop_close); 523 524 unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) 525 { 526 struct irctl *ir = irctls[iminor(file_inode(file))]; 527 unsigned int ret; 528 529 if (!ir) { 530 pr_err("called with invalid irctl\n"); 531 return POLLERR; 532 } 533 534 if (!ir->attached) 535 return POLLERR; 536 537 if (ir->buf) { 538 poll_wait(file, &ir->buf->wait_poll, wait); 539 540 if (lirc_buffer_empty(ir->buf)) 541 ret = 0; 542 else 543 ret = POLLIN | POLLRDNORM; 544 } else 545 ret = POLLERR; 546 547 dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n", 548 ir->d.name, ir->d.minor, ret); 549 550 return ret; 551 } 552 EXPORT_SYMBOL(lirc_dev_fop_poll); 553 554 long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 555 { 556 __u32 mode; 557 int result = 0; 558 struct irctl *ir = irctls[iminor(file_inode(file))]; 559 560 if (!ir) { 561 pr_err("no irctl found!\n"); 562 return -ENODEV; 563 } 564 565 dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", 566 ir->d.name, ir->d.minor, cmd); 567 568 if (ir->d.minor == NOPLUG || !ir->attached) { 569 dev_err(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n", 570 ir->d.name, ir->d.minor); 571 return -ENODEV; 572 } 573 574 mutex_lock(&ir->irctl_lock); 575 576 switch (cmd) { 577 case LIRC_GET_FEATURES: 578 result = put_user(ir->d.features, (__u32 __user *)arg); 579 break; 580 case LIRC_GET_REC_MODE: 581 if (!LIRC_CAN_REC(ir->d.features)) { 582 result = -ENOTTY; 583 break; 584 } 585 586 result = put_user(LIRC_REC2MODE 587 (ir->d.features & LIRC_CAN_REC_MASK), 588 (__u32 __user *)arg); 589 break; 590 case LIRC_SET_REC_MODE: 591 if (!LIRC_CAN_REC(ir->d.features)) { 592 result = -ENOTTY; 593 break; 594 } 595 596 result = get_user(mode, (__u32 __user *)arg); 597 if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) 598 result = -EINVAL; 599 /* 600 * FIXME: We should actually set the mode somehow but 601 * for now, lirc_serial doesn't support mode changing either 602 */ 603 break; 604 case LIRC_GET_LENGTH: 605 result = put_user(ir->d.code_length, (__u32 __user *)arg); 606 break; 607 case LIRC_GET_MIN_TIMEOUT: 608 if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || 609 ir->d.min_timeout == 0) { 610 result = -ENOTTY; 611 break; 612 } 613 614 result = put_user(ir->d.min_timeout, (__u32 __user *)arg); 615 break; 616 case LIRC_GET_MAX_TIMEOUT: 617 if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || 618 ir->d.max_timeout == 0) { 619 result = -ENOTTY; 620 break; 621 } 622 623 result = put_user(ir->d.max_timeout, (__u32 __user *)arg); 624 break; 625 default: 626 result = -EINVAL; 627 } 628 629 mutex_unlock(&ir->irctl_lock); 630 631 return result; 632 } 633 EXPORT_SYMBOL(lirc_dev_fop_ioctl); 634 635 ssize_t lirc_dev_fop_read(struct file *file, 636 char __user *buffer, 637 size_t length, 638 loff_t *ppos) 639 { 640 struct irctl *ir = irctls[iminor(file_inode(file))]; 641 unsigned char *buf; 642 int ret = 0, written = 0; 643 DECLARE_WAITQUEUE(wait, current); 644 645 if (!ir) { 646 pr_err("called with invalid irctl\n"); 647 return -ENODEV; 648 } 649 650 if (!LIRC_CAN_REC(ir->d.features)) 651 return -EINVAL; 652 653 dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor); 654 655 buf = kzalloc(ir->chunk_size, GFP_KERNEL); 656 if (!buf) 657 return -ENOMEM; 658 659 if (mutex_lock_interruptible(&ir->irctl_lock)) { 660 ret = -ERESTARTSYS; 661 goto out_unlocked; 662 } 663 if (!ir->attached) { 664 ret = -ENODEV; 665 goto out_locked; 666 } 667 668 if (length % ir->chunk_size) { 669 ret = -EINVAL; 670 goto out_locked; 671 } 672 673 /* 674 * we add ourselves to the task queue before buffer check 675 * to avoid losing scan code (in case when queue is awaken somewhere 676 * between while condition checking and scheduling) 677 */ 678 add_wait_queue(&ir->buf->wait_poll, &wait); 679 680 /* 681 * while we didn't provide 'length' bytes, device is opened in blocking 682 * mode and 'copy_to_user' is happy, wait for data. 683 */ 684 while (written < length && ret == 0) { 685 if (lirc_buffer_empty(ir->buf)) { 686 /* According to the read(2) man page, 'written' can be 687 * returned as less than 'length', instead of blocking 688 * again, returning -EWOULDBLOCK, or returning 689 * -ERESTARTSYS 690 */ 691 if (written) 692 break; 693 if (file->f_flags & O_NONBLOCK) { 694 ret = -EWOULDBLOCK; 695 break; 696 } 697 if (signal_pending(current)) { 698 ret = -ERESTARTSYS; 699 break; 700 } 701 702 mutex_unlock(&ir->irctl_lock); 703 set_current_state(TASK_INTERRUPTIBLE); 704 schedule(); 705 set_current_state(TASK_RUNNING); 706 707 if (mutex_lock_interruptible(&ir->irctl_lock)) { 708 ret = -ERESTARTSYS; 709 remove_wait_queue(&ir->buf->wait_poll, &wait); 710 goto out_unlocked; 711 } 712 713 if (!ir->attached) { 714 ret = -ENODEV; 715 goto out_locked; 716 } 717 } else { 718 lirc_buffer_read(ir->buf, buf); 719 ret = copy_to_user((void __user *)buffer+written, buf, 720 ir->buf->chunk_size); 721 if (!ret) 722 written += ir->buf->chunk_size; 723 else 724 ret = -EFAULT; 725 } 726 } 727 728 remove_wait_queue(&ir->buf->wait_poll, &wait); 729 730 out_locked: 731 mutex_unlock(&ir->irctl_lock); 732 733 out_unlocked: 734 kfree(buf); 735 736 return ret ? ret : written; 737 } 738 EXPORT_SYMBOL(lirc_dev_fop_read); 739 740 void *lirc_get_pdata(struct file *file) 741 { 742 return irctls[iminor(file_inode(file))]->d.data; 743 } 744 EXPORT_SYMBOL(lirc_get_pdata); 745 746 747 ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer, 748 size_t length, loff_t *ppos) 749 { 750 struct irctl *ir = irctls[iminor(file_inode(file))]; 751 752 if (!ir) { 753 pr_err("called with invalid irctl\n"); 754 return -ENODEV; 755 } 756 757 if (!ir->attached) 758 return -ENODEV; 759 760 return -EINVAL; 761 } 762 EXPORT_SYMBOL(lirc_dev_fop_write); 763 764 765 static int __init lirc_dev_init(void) 766 { 767 int retval; 768 769 lirc_class = class_create(THIS_MODULE, "lirc"); 770 if (IS_ERR(lirc_class)) { 771 pr_err("class_create failed\n"); 772 return PTR_ERR(lirc_class); 773 } 774 775 retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES, 776 IRCTL_DEV_NAME); 777 if (retval) { 778 class_destroy(lirc_class); 779 pr_err("alloc_chrdev_region failed\n"); 780 return retval; 781 } 782 783 784 pr_info("IR Remote Control driver registered, major %d\n", 785 MAJOR(lirc_base_dev)); 786 787 return 0; 788 } 789 790 791 792 static void __exit lirc_dev_exit(void) 793 { 794 class_destroy(lirc_class); 795 unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES); 796 pr_info("module unloaded\n"); 797 } 798 799 module_init(lirc_dev_init); 800 module_exit(lirc_dev_exit); 801 802 MODULE_DESCRIPTION("LIRC base driver module"); 803 MODULE_AUTHOR("Artur Lipowski"); 804 MODULE_LICENSE("GPL"); 805 806 module_param(debug, bool, S_IRUGO | S_IWUSR); 807 MODULE_PARM_DESC(debug, "Enable debugging messages"); 808