/* * Function irnet_find_lsap_sel (self) * * Try to lookup LSAP selector in remote LM-IAS * * Basically, we start a IAP query, and then go to sleep. When the query * return, irnet_getvalue_confirm will wake us up, and we can examine the * result of the query... * Note that in some case, the query fail even before we go to sleep, * creating some races... */ static int irnet_find_lsap_sel(irnet_socket * self) { DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self); /* This should not happen */ DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n"); /* Create an IAP instance, will be closed in irnet_getvalue_confirm() */ self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, irnet_getvalue_confirm); /* Treat unexpected signals as disconnect */ self->errno = -EHOSTUNREACH; /* Query remote LM-IAS */ iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr, IRNET_SERVICE_NAME, IRNET_IAS_VALUE); /* Wait for answer (if not already failed) */ if(self->iriap != NULL) interruptible_sleep_on(&self->query_wait); /* Check what happened */ if(self->errno) { DEBUG(IRDA_SR_INFO, "IAS query failed! (%d)\n", self->errno); /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) return (-EADDRNOTAVAIL); else return (-EHOSTUNREACH); } /* Get the remote TSAP selector */ switch(self->ias_result->type) { case IAS_INTEGER: DEBUG(IRDA_SR_INFO, "result=%d\n", self->ias_result->t.integer); if(self->ias_result->t.integer != -1) self->dtsap_sel = self->ias_result->t.integer; else self->dtsap_sel = 0; break; default: self->dtsap_sel = 0; DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", self->ias_result->type); break; } /* Cleanup */ if(self->ias_result) irias_delete_value(self->ias_result); DEXIT(IRDA_SR_TRACE, "\n"); if(self->dtsap_sel) return 0; return -EADDRNOTAVAIL; }
static inline __u8 irnet_ias_to_tsap(irnet_socket * self, int result, struct ias_value * value) { __u8 dtsap_sel = 0; DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self); self->errno = 0; switch(result) { case IAS_CLASS_UNKNOWN: case IAS_ATTRIB_UNKNOWN: DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result); self->errno = -EADDRNOTAVAIL; break; default : DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result); self->errno = -EHOSTUNREACH; break; case IAS_SUCCESS: break; } if(value != NULL) { switch(value->type) { case IAS_INTEGER: DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer); if(value->t.integer != -1) dtsap_sel = value->t.integer; else self->errno = -EADDRNOTAVAIL; break; default: self->errno = -EADDRNOTAVAIL; DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type); break; } irias_delete_value(value); } else { if(!(self->errno)) { DERROR(IRDA_SR_ERROR, "IrDA bug : result == SUCCESS && value == NULL\n"); self->errno = -EHOSTUNREACH; } } DEXIT(IRDA_SR_TRACE, "\n"); return(dtsap_sel); }