Ignore:
Timestamp:
May 19, 2009 2:25:41 PM (10 years ago)
Author:
bennylp
Message:

Ticket #857: Support for ICE keep-alive with Binding indication

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/sipit24/pjnath/src/pjnath/ice_session.c

    r2714 r2717  
    7676    TIMER_START_NOMINATED_CHECK,/**< Controlling agent start connectivity 
    7777                                     checks with USE-CANDIDATE flag.    */ 
    78                                          
     78    TIMER_KEEP_ALIVE            /**< ICE keep-alive timer.              */ 
    7979 
    8080}; 
     
    134134static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te); 
    135135static void on_ice_complete(pj_ice_sess *ice, pj_status_t status); 
     136static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now); 
    136137static void destroy_ice(pj_ice_sess *ice, 
    137138                        pj_status_t reason); 
     
    11121113        break; 
    11131114    case TIMER_COMPLETION_CALLBACK: 
     1115        /* Start keep-alive timer but don't send any packets yet. 
     1116         * Need to do it here just in case app destroy the session 
     1117         * in the callback. 
     1118         */ 
     1119        if (ice->ice_status == PJ_SUCCESS) 
     1120            ice_keep_alive(ice, PJ_FALSE); 
     1121 
     1122        /* Notify app about ICE completion*/ 
    11141123        if (ice->cb.on_ice_complete) 
    11151124            (*ice->cb.on_ice_complete)(ice, ice->ice_status); 
     
    11181127        start_nominated_check(ice); 
    11191128        break; 
     1129    case TIMER_KEEP_ALIVE: 
     1130        ice_keep_alive(ice, PJ_TRUE); 
     1131        break; 
     1132    } 
     1133} 
     1134 
     1135/* Send keep-alive */ 
     1136static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now) 
     1137{ 
     1138    if (send_now) { 
     1139        /* Send Binding Indication for the component */ 
     1140        pj_ice_sess_comp *comp = &ice->comp[ice->comp_ka]; 
     1141        pj_stun_tx_data *tdata; 
     1142        pj_ice_sess_check *the_check; 
     1143        pj_ice_msg_data *msg_data; 
     1144        int addr_len; 
     1145        pj_bool_t saved; 
     1146        pj_status_t status; 
     1147 
     1148        /* Must have nominated check by now */ 
     1149        pj_assert(comp->nominated_check != NULL); 
     1150        the_check = comp->nominated_check; 
     1151 
     1152        /* Create the Binding Indication */ 
     1153        status = pj_stun_session_create_ind(comp->stun_sess,  
     1154                                            PJ_STUN_BINDING_INDICATION, 
     1155                                            &tdata); 
     1156        if (status != PJ_SUCCESS) 
     1157            goto done; 
     1158 
     1159        /* Need the transport_id */ 
     1160        msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data); 
     1161        msg_data->transport_id = the_check->lcand->transport_id; 
     1162 
     1163        /* Temporarily disable FINGERPRINT. The Binding Indication  
     1164         * SHOULD NOT contain any attributes. 
     1165         */ 
     1166        saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_FALSE); 
     1167 
     1168        /* Send to session */ 
     1169        addr_len = pj_sockaddr_get_len(&the_check->rcand->addr); 
     1170        status = pj_stun_session_send_msg(comp->stun_sess, msg_data, 
     1171                                          PJ_FALSE, PJ_FALSE,  
     1172                                          &the_check->rcand->addr,  
     1173                                          addr_len, tdata); 
     1174 
     1175        /* Restore FINGERPRINT usage */ 
     1176        pj_stun_session_use_fingerprint(comp->stun_sess, saved); 
     1177 
     1178done: 
     1179        ice->comp_ka = (ice->comp_ka + 1) % ice->comp_cnt; 
     1180    } 
     1181 
     1182    if (ice->timer.id == TIMER_NONE) { 
     1183        pj_time_val delay = { 0, 0 }; 
     1184 
     1185        delay.msec = (PJ_ICE_SESS_KEEP_ALIVE_MIN +  
     1186                      (pj_rand() % PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND)) * 1000 /  
     1187                     ice->comp_cnt; 
     1188        pj_time_val_normalize(&delay); 
     1189 
     1190        ice->timer.id = TIMER_KEEP_ALIVE; 
     1191        pj_timer_heap_schedule(ice->stun_cfg.timer_heap, &ice->timer, &delay); 
     1192 
     1193    } else { 
     1194        pj_assert(!"Not expected any timer active"); 
    11201195    } 
    11211196} 
     
    26142689                                         unsigned src_addr_len) 
    26152690{ 
     2691    struct stun_data *sd; 
     2692 
    26162693    PJ_UNUSED_ARG(sess); 
    26172694    PJ_UNUSED_ARG(pkt); 
     
    26222699    PJ_UNUSED_ARG(src_addr_len); 
    26232700 
    2624     PJ_TODO(SUPPORT_RX_BIND_REQUEST_AS_INDICATION); 
    2625  
    2626     return PJ_ENOTSUP; 
     2701    sd = (struct stun_data*) pj_stun_session_get_user_data(sess); 
     2702 
     2703    if (msg->hdr.type == PJ_STUN_BINDING_INDICATION) { 
     2704        LOG5((sd->ice->obj_name, "Received Binding Indication keep-alive " 
     2705              "for component %d", sd->comp_id)); 
     2706    } else { 
     2707        LOG4((sd->ice->obj_name, "Received unexpected %s indication " 
     2708              "for component %d", pj_stun_get_method_name(msg->hdr.type),  
     2709              sd->comp_id)); 
     2710    } 
     2711 
     2712    return PJ_SUCCESS; 
    26272713} 
    26282714 
Note: See TracChangeset for help on using the changeset viewer.