21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/slab.h>
26 #include <linux/string.h>
33 #define DST_CA_ERROR 0
34 #define DST_CA_NOTICE 1
36 #define DST_CA_DEBUG 3
38 #define dprintk(x, y, z, format, arg...) do { \
40 if ((x > DST_CA_ERROR) && (x > y)) \
41 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
42 else if ((x > DST_CA_NOTICE) && (x > y)) \
43 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
44 else if ((x > DST_CA_INFO) && (x > y)) \
45 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
46 else if ((x > DST_CA_DEBUG) && (x > y)) \
47 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
50 printk(format, ## arg); \
56 static unsigned int verbose = 5;
61 static int ca_set_slot_descr(
void)
68 static int ca_set_pid(
void)
76 data[0] = (command >> 16) & 0xff;
77 data[1] = (command >> 8) & 0xff;
78 data[2] = command & 0xff;
82 static void put_checksum(
u8 *check_string,
int length)
117 if (
read_dst(state, ca_string, 128) < 0) {
132 static int dst_put_ci(
struct dst_state *state,
u8 *data,
int len,
u8 *ca_string,
int read)
134 u8 dst_ca_comm_err = 0;
136 while (dst_ca_comm_err <
RETRIES) {
138 if (dst_ci_command(state, data, ca_string, len, read)) {
154 static int ca_get_app_info(
struct dst_state *state)
157 static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
159 put_checksum(&command[0], command[0]);
160 if ((dst_put_ci(state, command,
sizeof(command), state->
messages,
GET_REPLY)) < 0) {
165 dprintk(
verbose,
DST_CA_INFO, 1,
" ================================ CI Module Application Info ======================================");
166 dprintk(
verbose,
DST_CA_INFO, 1,
" Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
169 dprintk(
verbose,
DST_CA_INFO, 1,
" ==================================================================================================");
173 str_length = length - 6;
174 if (str_length < 0) {
192 static int ca_get_ca_info(
struct dst_state *state)
194 int srcPtr, dstPtr,
i, num_ids;
195 static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff};
196 const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7;
198 put_checksum(&slot_command[0], slot_command[0]);
199 if ((dst_put_ci(state, slot_command,
sizeof (slot_command), state->
messages,
GET_REPLY)) < 0) {
207 for (i = 0; i < state->
messages[0] + 1; i++) {
213 num_ids = state->
messages[in_num_ids_pos];
214 if (num_ids >= 100) {
221 srcPtr = in_system_id_pos;
222 dstPtr = out_system_id_pos;
223 for(i = 0; i < num_ids; i++) {
236 static int ca_get_slot_caps(
struct dst_state *state,
struct ca_caps *p_ca_caps,
void __user *
arg)
240 static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff};
242 put_checksum(&slot_command[0], slot_command[0]);
243 if ((dst_put_ci(state, slot_command,
sizeof (slot_command), slot_cap,
GET_REPLY)) < 0) {
253 for (i = 0; i < slot_cap[0] + 1; i++)
269 static int ca_get_slot_descr(
struct dst_state *state,
struct ca_msg *p_ca_message,
void __user *arg)
275 static int ca_get_slot_info(
struct dst_state *state,
struct ca_slot_info *p_ca_slot_info,
void __user *arg)
278 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
282 put_checksum(&slot_command[0], 7);
283 if ((dst_put_ci(state, slot_command,
sizeof (slot_command), slot_info,
GET_REPLY)) < 0) {
293 for (i = 0; i < 8; i++)
297 if (slot_info[4] & 0x80) {
299 p_ca_slot_info->
num = 1;
301 }
else if (slot_info[4] & 0x40) {
303 p_ca_slot_info->
num = 1;
306 p_ca_slot_info->
flags = 0;
315 static int ca_get_message(
struct dst_state *state,
struct ca_msg *p_ca_message,
void __user *arg)
323 if (p_ca_message->
msg) {
325 3, p_ca_message->
msg);
327 for (i = 0; i < 3; i++) {
328 command = command | p_ca_message->
msg[
i];
330 command = command << 8;
351 static int handle_dst_tag(
struct dst_state *state,
struct ca_msg *p_ca_message,
struct ca_msg *hw_buffer,
u32 length)
354 hw_buffer->
msg[2] = p_ca_message->
msg[1];
355 hw_buffer->
msg[3] = p_ca_message->
msg[2];
361 hw_buffer->
msg[0] = (length & 0xff) + 7;
362 hw_buffer->
msg[1] = 0x40;
363 hw_buffer->
msg[2] = 0x03;
364 hw_buffer->
msg[3] = 0x00;
365 hw_buffer->
msg[4] = 0x03;
366 hw_buffer->
msg[5] = length & 0xff;
367 hw_buffer->
msg[6] = 0x00;
373 memcpy(&hw_buffer->
msg[7], &p_ca_message->
msg[4], length);
379 static int write_to_8820(
struct dst_state *state,
struct ca_msg *hw_buffer,
u8 length,
u8 reply)
381 if ((dst_put_ci(state, hw_buffer->
msg, length, hw_buffer->
msg, reply)) < 0) {
392 static u32 asn_1_decode(
u8 *asn_1_array)
394 u8 length_field = 0, word_count = 0,
count = 0;
397 length_field = asn_1_array[0];
399 if (length_field < 0x80) {
400 length = length_field & 0x7f;
403 word_count = length_field & 0x7f;
405 length = length << 8;
406 length += asn_1_array[
count + 1];
418 for (i = offset; i <
length; i++)
431 length = asn_1_decode(&p_ca_message->
msg[3]);
433 debug_string(&p_ca_message->
msg[4], length, 0);
436 handle_dst_tag(state, p_ca_message, hw_buffer, length);
437 put_checksum(hw_buffer->
msg, hw_buffer->
msg[0]);
439 debug_string(hw_buffer->
msg, (length + tag_length), 0);
440 write_to_8820(state, hw_buffer, (length + tag_length), reply);
447 static int dst_check_ca_pmt(
struct dst_state *state,
struct ca_msg *p_ca_message,
struct ca_msg *hw_buffer)
449 int ca_pmt_reply_test = 0;
455 if (ca_pmt_reply_test) {
456 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1,
GET_REPLY)) < 0) {
466 if (!ca_pmt_reply_test) {
467 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0,
NO_REPLY)) < 0) {
478 static int ca_send_message(
struct dst_state *state,
struct ca_msg *p_ca_message,
void __user *arg)
494 goto free_mem_and_exit;
498 if (p_ca_message->
msg) {
502 for (i = 0; i < 3; i++) {
503 command = command | p_ca_message->
msg[
i];
505 command = command << 8;
512 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
515 goto free_mem_and_exit;
522 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
525 goto free_mem_and_exit;
532 if ((ca_get_app_info(state)) < 0) {
535 goto free_mem_and_exit;
542 if ((ca_get_ca_info(state)) < 0) {
545 goto free_mem_and_exit;
563 struct ca_msg *p_ca_message;
573 if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) {
576 goto free_mem_and_exit;
583 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
586 goto free_mem_and_exit;
591 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
594 goto free_mem_and_exit;
605 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
608 goto free_mem_and_exit;
614 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
617 goto free_mem_and_exit;
623 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
626 goto free_mem_and_exit;
632 if ((ca_set_slot_descr()) < 0) {
635 goto free_mem_and_exit;
641 if ((ca_set_pid()) < 0) {
644 goto free_mem_and_exit;
651 kfree (p_ca_message);
652 kfree (p_ca_slot_info);
659 static int dst_ca_open(
struct inode *
inode,
struct file *file)
667 static int dst_ca_release(
struct inode *
inode,
struct file *file)
675 static ssize_t dst_ca_read(
struct file *file,
char __user *
buffer,
size_t length, loff_t *offset)
684 static ssize_t dst_ca_write(
struct file *file,
const char __user *
buffer,
size_t length, loff_t *offset)
693 .unlocked_ioctl = dst_ca_ioctl,
695 .release = dst_ca_release,
697 .write = dst_ca_write,