dvbca.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * libdvbca - interface onto raw CA devices
  3. *
  4. * Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library 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 GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include <sys/param.h>
  24. #include <sys/ioctl.h>
  25. #include <fcntl.h>
  26. #include <unistd.h>
  27. #include <ctype.h>
  28. #include <errno.h>
  29. #include <linux/dvb/ca.h>
  30. #include "dvbca.h"
  31. int dvbca_open(int adapter, int cadevice)
  32. {
  33. char filename[PATH_MAX+1];
  34. int fd;
  35. sprintf(filename, "/dev/dvb/adapter%i/ca%i", adapter, cadevice);
  36. if ((fd = open(filename, O_RDWR)) < 0) {
  37. // if that failed, try a flat /dev structure
  38. sprintf(filename, "/dev/dvb%i.ca%i", adapter, cadevice);
  39. fd = open(filename, O_RDWR);
  40. }
  41. return fd;
  42. }
  43. int dvbca_reset(int fd, uint8_t slot)
  44. {
  45. return ioctl(fd, CA_RESET, (1 << slot));
  46. }
  47. int dvbca_get_interface_type(int fd, uint8_t slot)
  48. {
  49. ca_slot_info_t info;
  50. info.num = slot;
  51. if (ioctl(fd, CA_GET_SLOT_INFO, &info))
  52. return -1;
  53. if (info.type & CA_CI_LINK)
  54. return DVBCA_INTERFACE_LINK;
  55. if (info.type & CA_CI)
  56. return DVBCA_INTERFACE_HLCI;
  57. return -1;
  58. }
  59. int dvbca_get_cam_state(int fd, uint8_t slot)
  60. {
  61. ca_slot_info_t info;
  62. info.num = slot;
  63. if (ioctl(fd, CA_GET_SLOT_INFO, &info))
  64. return -1;
  65. if (info.flags == 0)
  66. return DVBCA_CAMSTATE_MISSING;
  67. if (info.flags & CA_CI_MODULE_READY)
  68. return DVBCA_CAMSTATE_READY;
  69. if (info.flags & CA_CI_MODULE_PRESENT)
  70. return DVBCA_CAMSTATE_INITIALISING;
  71. return -1;
  72. }
  73. int dvbca_link_write(int fd, uint8_t slot, uint8_t connection_id,
  74. uint8_t *data, uint16_t data_length)
  75. {
  76. uint8_t *buf = malloc(data_length + 2);
  77. if (buf == NULL)
  78. return -1;
  79. buf[0] = slot;
  80. buf[1] = connection_id;
  81. memcpy(buf+2, data, data_length);
  82. int result = write(fd, buf, data_length+2);
  83. free(buf);
  84. return result;
  85. }
  86. int dvbca_link_read(int fd, uint8_t *slot, uint8_t *connection_id,
  87. uint8_t *data, uint16_t data_length)
  88. {
  89. int size;
  90. uint8_t *buf = malloc(data_length + 2);
  91. if (buf == NULL)
  92. return -1;
  93. if ((size = read(fd, buf, data_length+2)) < 2)
  94. return -1;
  95. *slot = buf[0];
  96. *connection_id = buf[1];
  97. memcpy(data, buf+2, size-2);
  98. free(buf);
  99. return size - 2;
  100. }
  101. int dvbca_hlci_write(int fd, uint8_t *data, uint16_t data_length)
  102. {
  103. struct ca_msg msg;
  104. if (data_length > 256) {
  105. return -1;
  106. }
  107. memset(&msg, 0, sizeof(msg));
  108. msg.length = data_length;
  109. memcpy(msg.msg, data, data_length);
  110. return ioctl(fd, CA_SEND_MSG, &msg);
  111. }
  112. int dvbca_hlci_read(int fd, uint32_t app_tag, uint8_t *data,
  113. uint16_t data_length)
  114. {
  115. struct ca_msg msg;
  116. if (data_length > 256) {
  117. data_length = 256;
  118. }
  119. memset(&msg, 0, sizeof(msg));
  120. msg.length = data_length;
  121. msg.msg[0] = app_tag >> 16;
  122. msg.msg[1] = app_tag >> 8;
  123. msg.msg[2] = app_tag;
  124. int status = ioctl(fd, CA_GET_MSG, &msg);
  125. if (status < 0) return status;
  126. if (msg.length > data_length) msg.length = data_length;
  127. memcpy(data, msg.msg, msg.length);
  128. return msg.length;
  129. }