int irda_irnet_connect(irnet_socket * self) { int err; DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self); if(test_and_set_bit(0, &self->ttp_connect)) DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n"); if((self->iriap != NULL) || (self->tsap != NULL)) DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n"); if((irnet_server.running) && (self->q.q_next == NULL)) { spin_lock_bh(&irnet_server.spinlock); hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname); spin_unlock_bh(&irnet_server.spinlock); DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname); } if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0')) { if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0) DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n"); } else { if(self->rdaddr == DEV_ADDR_ANY) { if((err = irnet_dname_to_daddr(self)) != 0) DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n"); } else self->daddr = self->rdaddr; irnet_find_lsap_sel(self); } DEXIT(IRDA_SOCK_TRACE, "\n"); return(0); }
/* * Function iriap_open (void) * * Opens an instance of the IrIAP layer, and registers with IrLMP */ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, CONFIRM_CALLBACK callback) { struct iriap_cb *self; IRDA_DEBUG(2, "%s()\n", __func__); self = kzalloc(sizeof(*self), GFP_ATOMIC); if (!self) { IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); return NULL; } /* * Initialize instance */ self->magic = IAS_MAGIC; self->mode = mode; if (mode == IAS_CLIENT) { if (iriap_register_lsap(self, slsap_sel, mode)) { kfree(self); return NULL; } } self->confirm = callback; self->priv = priv; /* iriap_getvaluebyclass_request() will construct packets before * we connect, so this must have a sane value... Jean II */ self->max_header_size = LMP_MAX_HEADER; init_timer(&self->watchdog_timer); hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL); /* Initialize state machines */ iriap_next_client_state(self, S_DISCONNECT); iriap_next_call_state(self, S_MAKE_CALL); iriap_next_server_state(self, R_DISCONNECT); iriap_next_r_connect_state(self, R_WAITING); return self; }
/* * Function iriap_open (void) * * Opens an instance of the IrIAP layer, and registers with IrLMP */ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, CONFIRM_CALLBACK callback) { struct iriap_cb *self; IRDA_DEBUG(2, __FUNCTION__ "()\n"); self = kmalloc(sizeof(struct iriap_cb), GFP_ATOMIC); if (!self) { WARNING(__FUNCTION__ "(), Unable to kmalloc!\n"); return NULL; } /* * Initialize instance */ memset(self, 0, sizeof(struct iriap_cb)); self->magic = IAS_MAGIC; self->mode = mode; if (mode == IAS_CLIENT) iriap_register_lsap(self, slsap_sel, mode); self->confirm = callback; self->priv = priv; init_timer(&self->watchdog_timer); hashbin_insert(iriap, (irda_queue_t *) self, (int) self, NULL); /* Initialize state machines */ iriap_next_client_state(self, S_DISCONNECT); iriap_next_call_state(self, S_MAKE_CALL); iriap_next_server_state(self, R_DISCONNECT); iriap_next_r_connect_state(self, R_WAITING); return self; }
/* * Connect to the other side : * o convert device name to an address * o find the socket number (dlsap) * o Establish the connection */ int irda_irnet_connect(irnet_socket * self) { int err; DENTER(IRDA_SOCK_TRACE, "(self=0x%X)\n", (unsigned int) self); /* Check if we have opened a local TSAP : * If we have already opened a TSAP, it means that either we are already * connected or in the process of doing so... */ if(self->tsap != NULL) DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n"); /* Insert ourselves in the hashbin so that the IrNET server can find us. * Notes : 4th arg is string of 32 char max and must be null terminated * When 4th arg is used (string), 3rd arg isn't (int) * Can't re-insert (MUST remove first) so check for that... */ if((irnet_server.running) && (self->q.q_next == NULL)) { unsigned long flags; spin_lock_irqsave(&irnet_server.spinlock, flags); hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname); spin_unlock_irqrestore(&irnet_server.spinlock, flags); DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname); } /* If we don't have anything (no address, no name) */ if((self->raddr == DEV_ADDR_ANY) && (self->rname[0] == '\0')) { /* Try to find a suitable address */ if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0) DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n"); } else { /* If we have only the name (no address), try to get an address */ if(self->raddr == DEV_ADDR_ANY) { if((err = irnet_dname_to_daddr(self)) != 0) DRETURN(err, IRDA_SOCK_INFO, "name-connect failed!\n"); } else /* Use the requested destination address */ self->daddr = self->raddr; /* Query remote LM-IAS to find LSAP selector */ if((err = irnet_find_lsap_sel(self)) != 0) DRETURN(err, IRDA_SOCK_INFO, "connect failed!\n"); } DEBUG(IRDA_SOCK_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n", self->daddr, self->dtsap_sel); /* Open a local TSAP (an IrTTP instance) */ err = irnet_open_tsap(self); DABORT(err != 0, err, IRDA_SOCK_ERROR, "connect aborted!\n"); /* Connect to remote device */ err = irttp_connect_request(self->tsap, self->dtsap_sel, self->saddr, self->daddr, NULL, self->max_sdu_size_rx, NULL); DABORT(err != 0, err, IRDA_SOCK_ERROR, "connect aborted!\n"); DEXIT(IRDA_SOCK_TRACE, "\n"); return(0); }