Porting miniDLNA to OpenBSD
Build
To compile and run minidlna the following libraries are needed. See ./minidlna/INSTALL
. So first step is to find and install all the packages which includes these libraries. One way is to do some searching in http://www.openports.se.
libexif
- Package:graphics/libexif
libjpeg
- Package:graphics/jpeg
libid3tag
- Package:audio/libid3tag
libFLAC
- Package:audio/flac
libvorbis
- Package:audio/libvorbis
sqlite3
- Package:databases/sqlite3
libavformat (the ffmpeg libraries)
- Package:graphics/ffmpeg
libuuid
- Package:/devel/uuid
orossp-uuid
?
I already had a few packages installed on my development machine.
gettext, libiconv, libidn, nano, ruby, wget
So I installed all the dependent packages ...
pkg_add libexif jpeg libid3tag flac libvorbis sqlite3 ffmpeg ossp-uuid
Next I try to compile the miniDLNA. Make complains about missing header files for the installed packages above. The headers aren't included in the packages as those are build to work with prebuilt applications. This means that the packages must be compiled locally from ports.
So next step is to install the ports source code. Get the source code from the install CD's and unpack them.
cd /usr
tar xzf ports.tar.gz
cd /usr/src
tar xzf src.tar.gz
tar xzf xenocara.tar.gz
Because binaries are already installed I would prefer not to recompile everything. First I try to do make fetch
to see if headers become available.
cd /usr/ports/graphics/libexif
make fetch
...
I don't think that was needed. The problem is that base include folder for installed packages in OpenBSD is /usr/local/include
instead of /usr/include
. So the solution is to change that in Makefile
and genconfig.sh
.
One difficult problem is that sendfile
is used. sendfile
is not supported on OpenBSD and need to be replaced by read
and write
in user space.
Another problem is regarding different network specification in Linux and OpenBSD. minidlna/getifaddr.c
calls functions that isn't supported in OpenBSD. The following functions needs to be reimplemented in OpenBSD.
int getifaddr(const char * ifname, char * buf, int len)
int getsysaddr(char * buf, int len)
int getsyshwaddr(char * buf, int len)
int get_remote_mac(struct in_addr ip_addr, unsigned char * mac)
This has been done in FreeBSD port and CVS HEAD.
__NR_clock_gettime
syscall can be replaced by CLOCK_GETTIME(2)
1.1 branch is now targetting multiple OS support using autoconf
. See autoconf and metaauto for more info. 1.1 branch in not stable yet.
To be continued ...
New attempt on minidlna
I tried to download the latest source from source forge. The version is a development version of 1.1.0 (1.0.24+).
http://minidlna.cvs.sourceforge.net/viewvc/minidlna/?view=tar&pathrev=HEAD
Development is now run from github:
https://github.com/glebius/minidlna
Looking at the links below I did my first attempts.
pkg_add autoconf
pkg_add automake
pkg_add libtool
export AUTOMAKE_VERSION=1.11
export AUTOCONF_VERSION=2.68
./autogen.sh
./configure
./configure
stumbled on avformat
lib which is part of ffmpeg library.
checking for av_open_input_file in -lavformat... no
configure: error: Could not find libavformat - part of ffmpeg
After some time banging the head against a wall (with configure
) I didn't know if I should try to skip autotools
and try to create a OpenBSD specific makefile (current FreeBSD port of minidlna 1.0.24 use that approach) or try to fix the problems with configure
.
Finally I downloaded the complete ports tree to find another port which use autotools
and avformat
. I finally found Aqualung. So the idea is to copy aqualung
port and use as basis for the minidlna port. Browsing the Makefile
for aqualung I realized that LDFLAGS
and CFLAGS
must be specified for configure
to work. From /ports/audio/aqualung/Makefile
.
CONFIGURE_STYLE=gnu
CONFIGURE_ENV= LDFLAGS="-pthread -L${LOCALBASE}/lib -L${X11BASE}/lib" \
CFLAGS="${CFLAGS} -DOSS_DEVICE='\"/dev/audio\"' \
-DPTHREAD_MIN_PRIORITY=0 -DPTHREAD_MAX_PRIORITY=31 \
-I${LOCALBASE}/include"
So I export those environment variables.
# export LDFLAGS="-pthread -L/usr/local/lib -L/usr/X11R6/lib"
# export CFLAGS="-DOSS_DEVICE='\"/dev/audio\"' -DPTHREAD_MIN_PRIORITY=0 -DPTHREAD_MAX_PRIORITY=31 -I/usr/local/include"
After comparing with FreeBSD I could trim the configuration.
# export LDFLAGS="-pthread -L/usr/local/lib"
# export CFLAGS="-I/usr/local/include"
I also downloaded aqualung
source to see if I could make that compile. To avoid any missing dependencies I also installed the package to get all depending libs.
pkg_add aqualung
As configure
worked I tried the same on minidlna
(still having the same environment variables) and, to my pleasant surprise, that worked as well. After ./configure
I could build a binary without a problem.
./configure
make
Check possible configure
options with -h
option.
./configure -h
The minidlna
binary even ran without a major problem.
# ./minidlna
[2012/05/25 16:05:26] minidlna.c:786: error: Usage:
./minidlna [-d] [-v] [-f config_file]
[-a listening_ip] [-p port]
[-s serial] [-m model_number]
[-t notify_interval] [-P pid_filename]
[-w url] [-R] [-V] [-h]
Notes:
Notify interval is in seconds. Default is 895 seconds.
Default pid file is /var/run/minidlna.pid.
With -d minidlna will run in debug mode (not daemonize).
-w sets the presentation url. Default is http address on port 80
-h displays this text
-R forces a full rescan
-L do note create playlists
-V print the version number
I made some small changes (e.g. specifying a proper media folder) to the default minidlna.conf
file and started the server.
./minidlna -R -d -f ./minidlna.conf
Starting "Windows Media Player" I could see the media server and play my favorite OpenBSD release songs over it.
Bug 3538219
When trying some more audio and video files I noticed a bug in minidlna. It's doesn't handle data transmission over socket completely. See more on.
send(res_buf) error - ID: 3538219
It seems that this issue isn't resolved yet in MAIN.
A proposed patch could be as follows.
Original
void
SendResp_upnphttp(struct upnphttp * h)
{
int n;
DPRINTF(E_DEBUG, L_HTTP, "HTTP RESPONSE: %.*s\n", h->res_buflen, h->res_buf);
n = send(h->socket, h->res_buf, h->res_buflen, 0);
if(n<0)
{
DPRINTF(E_ERROR, L_HTTP, "send(res_buf): %s\n", strerror(errno));
}
else if(n < h->res_buflen)
{
/* TODO : handle correctly this case */
DPRINTF(E_ERROR, L_HTTP, "send(res_buf): %d bytes sent (out of %d)\n",
n, h->res_buflen);
}
}
Updated version
void
SendResp_upnphttp(struct upnphttp * h)
{
int n, m = 0;
DPRINTF(E_DEBUG, L_HTTP, "HTTP RESPONSE: %.*s\n", h->res_buflen, h->res_buf);
while (m < h->res_buflen)
{
n = send(h->socket, h->res_buf + m, h->res_buflen - m, 0);
if(n<0)
{
DPRINTF(E_ERROR, L_HTTP, "send(res_buf): %s\n", strerror(errno));
break;
}
else if(n < h->res_buflen)
{
DPRINTF(E_DEBUG, L_HTTP, "send(res_buf): %d bytes sent (out of %d)\n",
n, h->res_buflen);
m += n;
}
}
}
I haven't tried this patch yet though.
Port have already been made ...
It seems like Stuart Henderson finalized a port before I had finished mine.
This is using current version 1.0.25 which doesn't use autotools so it requires a lot of patches. I didn't make any patches in my version from HEAD. Great that it is included anyhow. Shall be interesting to compare the autotools version with my initial work. Also don't understand how upnphttp.c
problem is avoided in current port.
1.1.0 was released April 4th 2013 which includes improved OS portability support.
DLNA testing
A set up required and optional media formats has been specified by DLNA alliance.
inotify support
As inotify isn't supported on BSD kqueue would be a good replacement on BSD's.
References
- http://sourceforge.net/projects/minidlna/
- http://sourceforge.net/projects/minidlna/files/minidlna/1.0.18/minidlna_1.0.18_src.tar.gz - CVS source
- Use sendfile to optimize data transfer
- getifaddr(3)
- minidlna: a new port needs testers, start-up script
- FreeBSD port of minidlna - Patches will eventually be merged back to main branch.
- Rygel - Gnome media server/renderer
- genconfig.sh - OpenBSD is included in
genconfig.sh
. - Compiling on OpenBSD
- Roku MyMedia - No only for Roku DVP
- Setup a Home Server with FreeBSD and ZFS
- MiniDLNA on MediaVault - source
- FreeBSD port of MiniDLNA
- How to Compile Wireshark on OpenBSD
- Building Suricata under OpenBSD
- Ongoing minidlna discussion
- Developer Tools for UPnP Technologies
- minidlna man page(Ubuntu)
- MiniDLNA on Ubtuntu
- ReadyDLNA
- UNIX Systems Porting Guidelines
- MiniDLNA on FreeNAS
- inotify on kqueue GSoC - Also see later discussion