Compare commits

..

2 Commits

Author SHA1 Message Date
Preston Baxter 7d45dde84e starting network things 2024-08-03 13:18:31 -05:00
Preston Baxter 69e26d6a55 tmp 2024-07-31 00:00:12 -05:00
3 changed files with 90 additions and 8 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@
*.mod.c
*.symvers
*.cache
*.o.d

View File

@ -3,7 +3,7 @@ obj-m += aes67.o
CC=gcc
KERN_DIR=/lib/modules/$(shell uname -r)/build/
host:
default:
$(MAKE) -C $(KERN_DIR) M=$$PWD modules
clean:
make -C $(KERN_DIR) M=$(PWD) clean

95
aes67.c
View File

@ -4,9 +4,14 @@
*
* */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <net/net_namespace.h>
#include <sound/pcm.h>
#include <sound/core.h>
#include <sound/initval.h>
@ -21,6 +26,8 @@ static struct platform_device *devices[SNDRV_CARDS];
#define CARD_NAME "AES67 Virtual Soundcard"
#define AES67_NET_SUCCESS 0
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
@ -38,9 +45,17 @@ MODULE_LICENSE("GPL");
/* Definistion of AES67 Virtual SoundCard */
struct aes67 {
/* ALSA Soundcard*/
struct snd_card *card;
/* PCM Device Soundcard*/
struct snd_pcm *pcm;
/* Linux Device */
struct device *dev;
/* Socket */
struct socket *socket;
/* Receiving Work Queue */
struct work_struct receive_work;
};
//Forward declarations
@ -49,7 +64,16 @@ static int snd_aes67_new_pcm(struct aes67 *virtcard);
/* Destructor */
static int snd_aes67_free(struct aes67 *virtcard)
{
/* free card */
snd_printk(KERN_INFO "Freeing Soundcard\n");
snd_card_free(virtcard->card);
/* free socket */
if (virtcard->socket) {
snd_printk(KERN_INFO "Freeing Socket\n");
sock_release(virtcard->socket);
}
kfree(virtcard);
return 0;
}
@ -91,6 +115,27 @@ static int snd_aes67_create(struct snd_card *card, struct aes67 **rvirtcard)
return err;
}
/* create socket */
err = sock_create_kern(&init_net, PF_INET, SOCK_DGRAM, IPPROTO_UDP,
&virtcard->socket);
if (err < 0) {
snd_printk(KERN_ERR
"Failed to create socket for virtual soundcard\n");
return err;
}
struct sockaddr_in addr = { .sin_family = AF_INET,
.sin_port = htons(9375),
.sin_addr = { htonl(INADDR_LOOPBACK) } };
virtcard->socket->ops->bind(virtcard->socket, (struct sockaddr *)&addr,
sizeof(addr));
if (err < 0) {
snd_printk(KERN_ERR
"Failed to bind socket for virtual soundcard\n");
return err;
}
/* Add PCM */
err = snd_aes67_new_pcm(virtcard);
if (err < 0) {
@ -99,7 +144,6 @@ static int snd_aes67_create(struct snd_card *card, struct aes67 **rvirtcard)
return err;
}
snd_printk(KERN_INFO "Successfully created AES67\n");
*rvirtcard = virtcard;
return 0;
@ -150,6 +194,39 @@ error:
snd_card_free(card);
return err;
}
/* Network functions */
static void aes67_rx_net(struct work_struct *work)
{
struct aes67 *virtcard = container_of(work, struct aes67, receive_work);
struct kvec iv;
struct msghdr msg = {};
size_t recv_buf_size = 4096;
int ret, buflen;
void *recv_buf;
/* Read lock socket */
/* Loop Receive */
recv_buf = kzalloc(recv_buf_size, GFP_KERNEL);
if (!recv_buf) {
snd_printk(KERN_ERR
"Failed to allocate network receive buffer\n");
return;
}
do {
iv.iov_base = recv_buf;
iv.iov_len = recv_buf_size;
msglen = kernel_recvmsg(virtcard->socket, &msg, &iv, 1, iv.iov_len, MSG_DONTWAIT);
} while (ret == AES67_NET_SUCCESS);
/* Handle stream end */
snd_printk(KERN_INFO "Finished Receiving work queue\n");
return;
}
/* PCM Shenaniagians */
/* Playback definition */
@ -243,9 +320,13 @@ static int snd_aes67_pcm_prepare(struct snd_pcm_substream *substream)
static int snd_aes67_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct aes67 *chip = snd_pcm_substream_chip(substream);
int err;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
/* do something to start the PCM engine */
INIT_WORK(&chip->receive_work, aes67_rx_net);
break;
case SNDRV_PCM_TRIGGER_STOP:
/* do something to stop the PCM engine */
@ -303,7 +384,8 @@ static int snd_aes67_new_pcm(struct aes67 *virtcard)
snd_printk(KERN_INFO "Initializing PCM for Virtual Soundcard");
err = snd_pcm_new(virtcard->card, CARD_NAME, 0, 1, 1, &pcm);
if (err < 0) {
snd_printk(KERN_INFO "Failed initializing PCM for Virtual Soundcard");
snd_printk(KERN_INFO
"Failed initializing PCM for Virtual Soundcard");
return err;
}
@ -319,8 +401,8 @@ static int snd_aes67_new_pcm(struct aes67 *virtcard)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_aes67_capture_ops);
/*Da buffers*/
snd_printk(KERN_INFO "Settig PCM managed buffer");
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DEV_LOWLEVEL, virtcard->dev, 64 * 1024,
64 * 1024);
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DEV_LOWLEVEL, virtcard->dev,
64 * 1024, 64 * 1024);
return 0;
}
@ -392,5 +474,4 @@ static void __exit alsa_card_aes67_exit(void)
platform_driver_unregister(&snd_aes67_driver);
}
module_init(alsa_card_aes67_init)
module_exit(alsa_card_aes67_exit)
module_init(alsa_card_aes67_init) module_exit(alsa_card_aes67_exit)