static int publish_presentity(struct sip_msg* _m, struct pdomain* _d, struct presentity* presentity) { event_t *parsed_event = NULL; int event_package = EVENT_OTHER; str callid = STR_STATIC_INIT("???"); int res; if (_m->event) parsed_event = (event_t *)_m->event->parsed; if (parsed_event) event_package = parsed_event->parsed; LOG(L_DBG, "publish_presentity: event_package=%d -1-\n", event_package); switch (event_package) { case EVENT_PRESENCE: res = publish_presence(_m, presentity); break; default: if (_m->callid) callid = _m->callid->body; LOG(L_WARN, "publish_presentity: no handler for event_package=%d" " callid=%.*s\n", event_package, callid.len, ZSW(callid.s)); paerrno = PA_EVENT_UNSUPP; res = -1; } return res; }
void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) { PurpleStoredImage *img; if ((img = purple_buddy_icons_find_account_icon(data->account))) { gconstpointer avatar_data; gsize avatar_len; avatar_data = purple_imgstore_get_data(img); avatar_len = purple_imgstore_get_size(img); if (_mdns_set_buddy_icon_data(data, avatar_data, avatar_len)) { /* The filename is a SHA-1 hash of the data (conveniently what we need) */ const char *p, *filename = purple_imgstore_get_filename(img); g_free(data->phsh); data->phsh = NULL; /* Get rid of the extension */ p = strchr(filename, '.'); if (p) data->phsh = g_strndup(filename, p - filename); else purple_debug_error("bonjour", "account buddy icon returned unexpected filename (%s)" "; unable to extract hash. Clearing buddy icon\n", filename); /* Update our TXT record */ publish_presence(data, PUBLISH_UPDATE); } purple_imgstore_unref(img); } else { /* We need to do this regardless of whether data->phsh is set so that we * cancel any icons that are currently in the process of being set */ _mdns_set_buddy_icon_data(data, NULL, 0); if (data->phsh != NULL) { /* Clear the buddy icon */ g_free(data->phsh); data->phsh = NULL; /* Update our TXT record */ publish_presence(data, PUBLISH_UPDATE); } } }
/** * Send a new dns-sd packet updating our status. */ void bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) { g_free(data->status); g_free(data->msg); data->status = g_strdup(status); data->msg = g_strdup(status_message); /* Update our text record with the new status */ publish_presence(data, PUBLISH_UPDATE); }
/** * Advertise our presence within the dns-sd daemon and start browsing * for other bonjour peers. */ gboolean bonjour_dns_sd_start(BonjourDnsSd *data) { /* Initialize the dns-sd data and session */ if (!_mdns_init_session(data)) return FALSE; /* Publish our bonjour IM client at the mDNS daemon */ if (!publish_presence(data, PUBLISH_START)) return FALSE; /* Advise the daemon that we are waiting for connections */ if (!_mdns_browse(data)) { purple_debug_error("bonjour", "Unable to get service.\n"); return FALSE; } return TRUE; }
void t_phone_user::handle_response_register(t_response *r, bool &re_register) { t_contact_param *c; unsigned long expires; unsigned long e; bool first_failure, first_success; re_register = false; // Store the destination IP address/port of the REGISTER message. // To this destination the NAT keep alive packets will be sent. t_request *req = r_register->get_request(); req->get_destination(register_ip_port, *user_config); switch(r->get_class()) { case R_2XX: last_reg_failed = false; // Stop registration timer if one was running phone->stop_timer(PTMR_REGISTRATION, this); c = r->hdr_contact.find_contact(req->hdr_contact.contact_list.front().uri); if (!c) { if (!user_config->get_allow_missing_contact_reg()) { is_registered = false; log_file->write_report( "Contact header is missing.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, "Contact header missing."); cleanup_registration_data(); return; } else { log_file->write_report( "Cannot find matching contact header.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_DEBUG); } } if (c && c->is_expires_present() && c->get_expires() != 0) { expires = c->get_expires(); } else if (r->hdr_expires.is_populated() && r->hdr_expires.time != 0) { expires = r->hdr_expires.time; } else { if (!user_config->get_allow_missing_contact_reg()) { is_registered = false; log_file->write_report( "Expires parameter/header mising.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, "Expires parameter/header mising."); cleanup_registration_data(); return; } expires = user_config->get_registration_time(); // Assume a default expiration of 3600 sec if no expiry // time was returned. if (expires == 0) expires = 3600; } // Start new registration timer // The maximum value of the timer can be 2^32-1 s // The maximum timer that we can handle however is 2^31-1 ms e = (expires > 2147483 ? 2147483 : expires); phone->start_set_timer(PTMR_REGISTRATION, e * 1000, this); // Save the Service-Route if present the response contains any // RFC 3608 6 // Collect the service route to route later initial requests. if (r->hdr_service_route.is_populated()) { service_route = r->hdr_service_route.route_list; log_file->write_header("t_phone_user::handle_response_register"); log_file->write_raw("Store service route:\n"); for (list<t_route>::const_iterator it = service_route.begin(); it != service_route.end(); ++it) { log_file->write_raw(it->encode()); log_file->write_endl(); } log_file->write_footer(); } else { if (!service_route.empty()) { log_file->write_report("Clear service route.", "t_phone_user::handle_response_register"); service_route.clear(); } } first_success = !is_registered; is_registered = true; ui->cb_register_success(user_config, r, expires, first_success); // Start sending NAT keepalive packets when STUN is used // (or in case of symmetric firewall) if (use_nat_keepalive && id_nat_keepalive == 0) { // Just start the NAT keepalive timer. The REGISTER // message itself created the NAT binding. So there is // no need to send a NAT keep alive packet now. phone->start_timer(PTMR_NAT_KEEPALIVE, this); } // Start sending TCP ping packets on persistent TCP connections. if (user_config->get_persistent_tcp() && id_tcp_ping == 0) { phone->start_timer(PTMR_TCP_PING, this); } // Registration succeeded. If sollicited MWI is provisioned // and no MWI subscription is established yet, then subscribe // to MWI. if (user_config->get_mwi_sollicited() && !mwi_auto_resubscribe) { subscribe_mwi(); } // Publish presence state if not yet published. if (user_config->get_pres_publish_startup() && presence_epa->get_epa_state() == t_epa::EPA_UNPUBLISHED) { publish_presence(t_presence_state::ST_BASIC_OPEN); } // Subscribe to buddy list presence if not done so. if (!buddy_list->get_is_subscribed()) { subscribe_presence(); } break; case R_4XX: is_registered = false; // RFC 3261 10.3 if (r->code == R_423_INTERVAL_TOO_BRIEF) { if (!r->hdr_min_expires.is_populated()) { // Violation of RFC 3261 10.3 item 7 log_file->write_report("Min-Expires header missing from 423 response.", "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, "Min-Expires header missing."); cleanup_registration_data(); return; } if (r->hdr_min_expires.time <= registration_time) { // Wrong Min-Expires time string s = "Min-Expires ("; s += ulong2str(r->hdr_min_expires.time); s += ") is smaller than the requested "; s += "time ("; s += ulong2str(registration_time); s += ")"; log_file->write_report(s, "t_phone_user::handle_response_register", LOG_NORMAL, LOG_WARNING); ui->cb_invalid_reg_resp(user_config, r, s); cleanup_registration_data(); return; } // Automatic re-register with Min-Expires time registration_time = r->hdr_min_expires.time; re_register = true; // No need to cleanup STUN data as a new REGISTER will be // sent immediately. return; } // If authorization failed, then do not start the continuous // re-attempts. When authorization fails the user is asked // for credentials (in GUI). So the user cancelled these // questions and should not be bothered with the same question // again every 30 seconds. The user does not have the // credentials. if (r->code == R_401_UNAUTHORIZED || r->code == R_407_PROXY_AUTH_REQUIRED) { last_reg_failed = true; ui->cb_register_failed(user_config, r, true); cleanup_registration_data(); return; } // fall thru default: first_failure = !last_reg_failed; last_reg_failed = true; is_registered = false; authorizor.remove_from_cache(""); // Clear credentials cache ui->cb_register_failed(user_config, r, first_failure); phone->start_set_timer(PTMR_REGISTRATION, DUR_REG_FAILURE * 1000, this); cleanup_registration_data(); } }