diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 4fd959f44a..2abc5b342a 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -60,15 +60,18 @@ MODULE_LICENSE("Dual BSD/GPL"); static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */ -#define GIOVA_BLK 1920 -#define GIOVA_SLEEP 20 +static int unload = 0; +#ifdef CENTOS +#define HRTIMER_MODE_REL HRTIMER_REL +#endif// CENTOS +#ifndef WANT_HRTIMER void my_timer_callback_inq( unsigned long data ) { struct skypopen_dev *dev = (void *)data; wake_up_interruptible(&dev->inq); - mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); } @@ -77,8 +80,66 @@ void my_timer_callback_outq( unsigned long data ) struct skypopen_dev *dev = (void *)data; wake_up_interruptible(&dev->outq); - mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); } +#else// WANT_HRTIMER + +#ifndef CENTOS +static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq ) +{ + struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); + ktime_t now; + + if(unload) + return HRTIMER_NORESTART; + + now = ktime_get(); + hrtimer_forward(&dev->timer_inq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->inq); + + return HRTIMER_RESTART; +} +static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq ) +{ + struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq); + ktime_t now; + + if(unload) + return HRTIMER_NORESTART; + + now = ktime_get(); + hrtimer_forward(&dev->timer_outq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->outq); + + return HRTIMER_RESTART; +} +#else// CENTOS +static int my_hrtimer_callback_inq( struct hrtimer *timer_inq ) +{ + struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); + + if(unload) + return HRTIMER_NORESTART; + + hrtimer_forward(&dev->timer_inq, timer_inq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->inq); + + return HRTIMER_RESTART; +} +static int my_hrtimer_callback_outq( struct hrtimer *timer_outq ) +{ + struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq); + + if(unload) + return HRTIMER_NORESTART; + + hrtimer_forward(&dev->timer_outq, timer_outq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->outq); + + return HRTIMER_RESTART; +} +#endif// CENTOS +#endif// WANT_HRTIMER /* The clone-specific data structure includes a key field */ @@ -97,6 +158,12 @@ static spinlock_t skypopen_c_lock = SPIN_LOCK_UNLOCKED; static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) { struct skypopen_listitem *lptr; +#ifdef WANT_HRTIMER +#if 0 + ktime_t ktime_inq; + ktime_t ktime_outq; +#endif //0 +#endif// WANT_HRTIMER list_for_each_entry(lptr, &skypopen_c_list, list) { if (lptr->key == key) @@ -112,14 +179,29 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) memset(lptr, 0, sizeof(struct skypopen_listitem)); lptr->key = key; - init_waitqueue_head(&lptr->device.inq); - init_waitqueue_head(&lptr->device.outq); - setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); - setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); - printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); - mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); - printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); - mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + init_waitqueue_head(&lptr->device.inq); + init_waitqueue_head(&lptr->device.outq); +#ifndef WANT_HRTIMER + setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); + setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); + printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); + mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); + printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); + mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); +#else// WANT_HRTIMER +#if 0 + ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &lptr->device.timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + lptr->device.timer_inq.function = &my_hrtimer_callback_inq; + hrtimer_start( &lptr->device.timer_inq, ktime_inq, HRTIMER_MODE_REL ); + + ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &lptr->device.timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + lptr->device.timer_outq.function = &my_hrtimer_callback_outq; + hrtimer_start( &lptr->device.timer_outq, ktime_outq, HRTIMER_MODE_REL ); +#endif + +#endif// WANT_HRTIMER /* place it in the list */ list_add(&lptr->list, &skypopen_c_list); @@ -135,7 +217,7 @@ static int skypopen_c_open(struct inode *inode, struct file *filp) struct skypopen_dev *dev; dev_t key; - key = current->pid; + key = current->tgid; /* look for a skypopenc device in the list */ spin_lock(&skypopen_c_lock); @@ -163,12 +245,27 @@ static int skypopen_c_release(struct inode *inode, struct file *filp) /*************************************************************/ -ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, +static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { - struct skypopen_dev *dev = filp->private_data; DEFINE_WAIT(wait); + struct skypopen_dev *dev = filp->private_data; +#ifdef WANT_HRTIMER +#if 1 + if(dev->timer_inq_started == 0){ + ktime_t ktime_inq; + ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &dev->timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + dev->timer_inq.function = &my_hrtimer_callback_inq; + hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL ); + dev->timer_inq_started = 1; + } +#endif +#endif// WANT_HRTIMER + + + //printk("READ\n"); prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->inq, &wait); @@ -176,12 +273,27 @@ ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, } -ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, +static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { - struct skypopen_dev *dev = filp->private_data; DEFINE_WAIT(wait); + struct skypopen_dev *dev = filp->private_data; +#ifdef WANT_HRTIMER +#if 1 + if(dev->timer_outq_started == 0){ + ktime_t ktime_outq; + ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &dev->timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + dev->timer_outq.function = &my_hrtimer_callback_outq; + hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL ); + dev->timer_outq_started = 1; + } +#endif +#endif// WANT_HRTIMER + + + //printk("WRITE\n"); prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->outq, &wait); @@ -192,7 +304,7 @@ ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, * The ioctl() implementation */ -int skypopen_ioctl(struct inode *inode, struct file *filp, +static int skypopen_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; @@ -202,7 +314,7 @@ int skypopen_ioctl(struct inode *inode, struct file *filp, case OSS_GETVERSION: return put_user(SOUND_VERSION, p); case SNDCTL_DSP_GETBLKSIZE: - return put_user(GIOVA_BLK, p); + return put_user(SKYPOPEN_BLK, p); case SNDCTL_DSP_GETFMTS: return put_user(28731, p); @@ -239,6 +351,11 @@ void skypopen_cleanup_module(void) struct skypopen_listitem *lptr, *next; dev_t devno = MKDEV(skypopen_major, skypopen_minor); + + unload = 1; + + msleep(100); + /* Get rid of our char dev entries */ if (skypopen_devices) { for (i = 0; i < skypopen_nr_devs; i++) { @@ -247,13 +364,20 @@ void skypopen_cleanup_module(void) kfree(skypopen_devices); } - /* And all the cloned devices */ list_for_each_entry_safe(lptr, next, &skypopen_c_list, list) { +#ifndef WANT_HRTIMER ret= del_timer( &lptr->device.timer_inq ); - //printk( "Stopped skypopen OSS driver read timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); + printk( "Stopped skypopen OSS driver read timer\n"); ret= del_timer( &lptr->device.timer_outq ); - //printk( "Stopped skypopen OSS driver write timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); + printk( "Stopped skypopen OSS driver write timer\n"); +#else// WANT_HRTIMER + ret = hrtimer_cancel( &lptr->device.timer_inq ); + printk( "Stopped skypopen OSS driver read HRtimer\n"); + ret = hrtimer_cancel( &lptr->device.timer_outq ); + printk( "Stopped skypopen OSS driver write HRtimer\n"); + +#endif// WANT_HRTIMER list_del(&lptr->list); kfree(lptr); } diff --git a/src/mod/endpoints/mod_skypopen/oss/skypopen.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h index 5469048c04..2324e448cb 100644 --- a/src/mod/endpoints/mod_skypopen/oss/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/oss/skypopen.h @@ -20,6 +20,11 @@ #include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */ +#define SKYPOPEN_BLK 960 +#define SKYPOPEN_SLEEP 10 + +#define CENTOS + #ifndef SKYPOPEN_MAJOR #define SKYPOPEN_MAJOR 14 /* dynamic major by default */ #endif @@ -28,12 +33,18 @@ #define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */ #endif +#define WANT_HRTIMER struct skypopen_dev { struct cdev cdev; /* Char device structure */ wait_queue_head_t inq; /* read and write queues */ wait_queue_head_t outq; /* read and write queues */ +#ifndef WANT_HRTIMER struct timer_list timer_inq; struct timer_list timer_outq; +#else// WANT_HRTIMER + struct hrtimer timer_inq; + struct hrtimer timer_outq; +#endif// WANT_HRTIMER int timer_inq_started; int timer_outq_started; }; @@ -50,11 +61,11 @@ extern int skypopen_nr_devs; * Prototypes for shared functions */ -ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, - loff_t *f_pos); -ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos); -int skypopen_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +//ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, + //loff_t *f_pos); +//ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, + //loff_t *f_pos); +//int skypopen_ioctl(struct inode *inode, struct file *filp, + //unsigned int cmd, unsigned long arg); #endif /* _SKYPOPEN_H_ */ diff --git a/src/switch_channel.c b/src/switch_channel.c index b0ee9f527c..ef21e8c8f1 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2386,6 +2386,8 @@ SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *chann { switch_assert(channel != NULL); + switch_channel_set_flag(channel, CF_DIALPLAN); + switch_mutex_lock(channel->profile_mutex); caller_extension->next = channel->caller_profile->caller_extension; channel->caller_profile->caller_extension = caller_extension; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 59cc17d33a..ccd6dacc9c 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -123,9 +123,7 @@ static void switch_core_standard_on_routing(switch_core_session_t *session) } } - if (count) { - switch_channel_set_flag(session->channel, CF_DIALPLAN); - } else { + if (!count) { if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { if (switch_channel_test_flag(session->channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,