27 #include <linux/module.h>
28 #include <linux/types.h>
31 #include <linux/string.h>
34 #include <linux/slab.h>
36 #include <asm/byteorder.h>
37 #include <asm/unaligned.h>
46 #ifdef CONFIG_IRDA_DEBUG
48 static const char *
const ias_charset_types[] = {
64 static void *service_handle;
66 static void __iriap_close(
struct iriap_cb *
self);
67 static int iriap_register_lsap(
struct iriap_cb *
self,
__u8 slsap_sel,
int mode);
68 static void iriap_disconnect_indication(
void *instance,
void *sap,
70 static void iriap_connect_indication(
void *instance,
void *sap,
74 static void iriap_connect_confirm(
void *instance,
void *sap,
78 static int iriap_data_indication(
void *instance,
void *sap,
81 static void iriap_watchdog_timer_expired(
void *
data);
83 static inline void iriap_start_watchdog_timer(
struct iriap_cb *
self,
86 irda_start_timer(&self->watchdog_timer, timeout,
self,
87 iriap_watchdog_timer_expired);
113 IRDA_WARNING(
"%s: Can't allocate irias_objects hashbin!\n",
135 #ifdef CONFIG_IRDA_ULTRA
148 IRDA_DEBUG(0,
"%s(), unable to open server\n", __func__);
195 iriap_register_lsap(
self, slsap_sel, mode);
224 static void __iriap_close(
struct iriap_cb *
self)
233 if (self->request_skb)
234 dev_kfree_skb(self->request_skb);
285 if (self->lsap ==
NULL) {
286 IRDA_ERROR(
"%s: Unable to allocated LSAP!\n", __func__);
289 self->slsap_sel =
self->lsap->slsap_sel;
300 static void iriap_disconnect_indication(
void *instance,
void *sap,
322 IRDA_DEBUG(4,
"%s(), disconnect as client\n", __func__);
335 IRDA_DEBUG(4,
"%s(), disconnect as server\n", __func__);
345 static void iriap_disconnect_request(
struct iriap_cb *
self)
355 if (tx_skb ==
NULL) {
357 "%s(), Could not allocate an sk_buff of length %d\n",
400 iriap_start_watchdog_timer(
self, 10*
HZ);
405 skb_len =
self->max_header_size+2+name_len+1+attr_len+4;
411 skb_reserve(tx_skb, self->max_header_size);
412 skb_put(tx_skb, 3+name_len+attr_len);
413 frame = tx_skb->
data;
418 memcpy(frame+2, name, name_len);
420 memcpy(frame+3+name_len, attr, attr_len);
425 dev_kfree_skb(tx_skb);
438 static void iriap_getvaluebyclass_confirm(
struct iriap_cb *
self,
460 len = get_unaligned_be16(fp + n);
463 IRDA_DEBUG(4,
"%s(), len=%d\n", __func__, len);
466 obj_id = get_unaligned_be16(fp + n);
470 IRDA_DEBUG(4,
"%s(), Value type = %d\n", __func__, type);
474 memcpy(&tmp_cpu32, fp+n, 4); n += 4;
498 IRDA_DEBUG(0,
"%s(), charset %s, not supported\n",
499 __func__, ias_charset_types[charset]);
502 iriap_disconnect_request(
self);
507 IRDA_DEBUG(4,
"%s(), strlen=%d\n", __func__, value_len);
510 if (n + value_len < skb->len)
518 value_len = get_unaligned_be16(fp + n);
530 iriap_disconnect_request(
self);
536 self->confirm(
IAS_SUCCESS, obj_id, value, self->priv);
538 IRDA_DEBUG(0,
"%s(), missing handler!\n", __func__);
549 static void iriap_getvaluebyclass_response(
struct iriap_cb *
self,
575 tx_skb = alloc_skb(value->
len + self->max_header_size + 32,
581 skb_reserve(tx_skb, self->max_header_size);
591 tmp_be16 =
htons(0x0001);
592 memcpy(fp+n, &tmp_be16, 2); n += 2;
596 memcpy(fp+n, &tmp_be16, 2); n += 2;
598 switch (value->
type) {
601 fp[n++] = value->
type;
608 fp[n++] = value->
type;
611 memcpy(fp+n, &tmp_be32, 4); n += 4;
615 fp[n++] = value->
type;
618 memcpy(fp+n, &tmp_be16, 2); n += 2;
622 IRDA_DEBUG( 3,
"%s: sending IAS_MISSING\n", __func__);
624 fp[n++] = value->
type;
627 IRDA_DEBUG(0,
"%s(), type not implemented!\n", __func__);
633 dev_kfree_skb(tx_skb);
642 static void iriap_getvaluebyclass_indication(
struct iriap_cb *
self,
674 memcpy(attr, fp+n, attr_len); n+=attr_len;
675 attr[attr_len] =
'\0';
677 IRDA_DEBUG(4,
"LM-IAS: Looking up %s: %s\n", name, attr);
681 IRDA_DEBUG(2,
"LM-IAS: Object %s not found\n", name);
689 if (attrib ==
NULL) {
690 IRDA_DEBUG(2,
"LM-IAS: Attribute %s not found\n", attr);
691 iriap_getvaluebyclass_response(
self, obj->
id,
723 skb_reserve(tx_skb, self->max_header_size);
725 frame = tx_skb->
data;
741 self->saddr, self->daddr,
744 IRDA_DEBUG(0,
"%s(), connect failed!\n", __func__);
755 static void iriap_connect_confirm(
void *instance,
void *sap,
757 __u8 max_header_size,
768 self->max_data_size = max_seg_size;
785 static void iriap_connect_indication(
void *instance,
void *sap,
787 __u8 max_header_size,
803 IRDA_DEBUG(0,
"%s(), open failed\n", __func__);
810 IRDA_DEBUG(0,
"%s(), dup failed!\n", __func__);
814 new->max_data_size = max_seg_size;
818 irlmp_listen(self->lsap);
833 static int iriap_data_indication(
void *instance,
void *sap,
852 IRDA_DEBUG(4,
"%s(), Calling server!\n", __func__);
859 "results is not implemented yet!\n",
866 IRDA_DEBUG(0,
"%s() Got ack frame!\n", __func__);
874 IRDA_DEBUG(0,
"IrLMP GetInfoBaseDetails not implemented!\n");
881 iriap_getvaluebyclass_confirm(
self, skb);
884 IRDA_DEBUG(1,
"%s(), No such class!\n", __func__);
886 iriap_disconnect_request(
self);
897 IRDA_DEBUG(1,
"%s(), No such attribute!\n", __func__);
899 iriap_disconnect_request(
self);
912 IRDA_DEBUG(0,
"%s(), Unknown op-code: %02x\n", __func__,
943 if (~opcode & 0x80) {
944 IRDA_WARNING(
"%s: IrIAS multiframe commands or results "
945 "is not implemented yet!\n", __func__);
952 IRDA_WARNING(
"%s: GetInfoBaseDetails not implemented yet!\n",
956 iriap_getvaluebyclass_indication(
self, skb);
968 static void iriap_watchdog_timer_expired(
void *
data)
978 #ifdef CONFIG_PROC_FS
980 static const char *
const ias_value_types[] = {
1000 static void *irias_seq_start(
struct seq_file *seq, loff_t *pos)
1007 static void *irias_seq_next(
struct seq_file *seq,
void *
v, loff_t *pos)
1016 static void irias_seq_stop(
struct seq_file *seq,
void *v)
1021 static int irias_seq_show(
struct seq_file *seq,
void *v)
1024 seq_puts(seq,
"LM-IAS Objects:\n");
1047 seq_printf(seq,
" - Attribute name: \"%s\", ",
1050 ias_value_types[attrib->
value->type]);
1052 switch (attrib->
value->type) {
1055 attrib->
value->t.integer);
1059 attrib->
value->t.string);
1062 seq_printf(seq,
"octet sequence (%d bytes)\n",
1063 attrib->
value->len);
1070 attrib->
value->type);
1076 spin_unlock(&obj->attribs->hb_spinlock);
1083 .
start = irias_seq_start,
1084 .next = irias_seq_next,
1085 .stop = irias_seq_stop,
1086 .show = irias_seq_show,
1093 return seq_open(file, &irias_seq_ops);
1098 .open = irias_seq_open,