diff --git a/dvbls/README b/dvbls/README new file mode 100644 index 0000000..7494499 --- /dev/null +++ b/dvbls/README @@ -0,0 +1,22 @@ +# LICENSE + + Copyright (C) 2012, Andrey Dyldin + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + diff --git a/dvbls/dvbls.c b/dvbls/dvbls.c new file mode 100644 index 0000000..af7b96e --- /dev/null +++ b/dvbls/dvbls.c @@ -0,0 +1,158 @@ +/* + * dvbls + * Copyright (C) 2012, Andrey Dyldin +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int adapter = 0; +static int device = 0; +static char dev_name[512]; + +static void iterate_dir(const char *dir, const char *filter, void (*callback)(const char *)) +{ + DIR *dirp = opendir(dir); + if(!dirp) + { + printf("ERROR: opendir() failed %s [%s]\n", dir, strerror(errno)); + return; + } + + char item[64]; + const int item_len = sprintf(item, "%s/", dir); + const int filter_len = strlen(filter); + do + { + struct dirent *entry = readdir(dirp); + if(!entry) + break; + if(strncmp(entry->d_name, filter, filter_len)) + continue; + sprintf(&item[item_len], "%s", entry->d_name); + callback(item); + } while(1); + + closedir(dirp); +} + +static int get_last_int(const char *str) +{ + int i = 0; + int i_pos = -1; + for(; str[i]; ++i) + { + const char c = str[i]; + if(c >= '0' && c <= '9') + { + if(i_pos == -1) + i_pos = i; + } + else if(i_pos >= 0) + i_pos = -1; + } + + if(i_pos == -1) + return 0; + + return atoi(&str[i_pos]); +} + +static void check_device_net(void) +{ + sprintf(dev_name, "/dev/dvb/adapter%d/net%d", adapter, device); + + int fd = open(dev_name, O_RDWR | O_NONBLOCK); + if(!fd) + { + printf("ERROR: open() failed %s [%s]\n", dev_name, strerror(errno)); + return; + } + + struct dvb_net_if net = { 0, 0 ,0 }; + if(ioctl(fd, NET_ADD_IF, &net) < 0) + { + printf("ERROR: NET_ADD_IF failed %s [%s]\n", dev_name, strerror(errno)); + close(fd); + return; + } + + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + sprintf(ifr.ifr_name, "dvb%d_%d", adapter, device); + + int sock = socket(PF_INET, SOCK_DGRAM, 0); + if(ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) + printf("ERROR: SIOCGIFHWADDR failed %s [%s]\n", dev_name, strerror(errno)); + else + { + const unsigned char *mac = ifr.ifr_hwaddr.sa_data; + printf(" mac:%02X:%02X:%02X:%02X:%02X:%02X\n" + , mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + } + close(sock); + + if(ioctl(fd, NET_REMOVE_IF, net.if_num) < 0) + printf("ERROR: NET_REMOVE_IF failed %s [%s]\n", dev_name, strerror(errno)); + + close(fd); +} + +static void check_device_frontend(void) +{ + sprintf(dev_name, "/dev/dvb/adapter%d/frontend%d", adapter, device); + + int fd = open(dev_name, O_RDONLY | O_NONBLOCK); + if(!fd) + { + printf("ERROR: open() failed %s [%s]\n", dev_name, strerror(errno)); + return; + } + + struct dvb_frontend_info feinfo; + if(ioctl(fd, FE_GET_INFO, &feinfo) < 0) + { + printf("ERROR: FE_GET_INFO failed %s [%s]\n", dev_name, strerror(errno)); + close(fd); + return; + } + + printf(" frontend:%s\n", feinfo.name); + + close(fd); +} + +static void check_device(const char *item) +{ + device = get_last_int(&item[(sizeof("/dev/dvb/adapter") - 1) + (sizeof("/net") - 1)]); + + printf("adapter:%d device:%d\n", adapter, device); + check_device_frontend(); + check_device_net(); + printf("\n"); +} + +static void check_adapter(const char *item) +{ + adapter = get_last_int(&item[sizeof("/dev/dvb/adapter") - 1]); + iterate_dir(item, "net", check_device); +} + +int main(int argc, char const *argv[]) +{ + printf("dvbls v.1\n\n"); + iterate_dir("/dev/dvb", "adapter", check_adapter); + return 0; +} diff --git a/dvbls/install.sh b/dvbls/install.sh new file mode 100755 index 0000000..daeb7e3 --- /dev/null +++ b/dvbls/install.sh @@ -0,0 +1,2 @@ +#!/bin/bash +sudo gcc -o /usr/local/bin/dvbls dvbls.c diff --git a/install.sh b/install.sh index 1a5478b..33215c7 100755 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/bin/bash # Enable some staging drivers -make stagingconfig +#make stagingconfig echo "V4L drivers building..." make -j5