New question #191211 on rohc:
https://answers.launchpad.net/rohc/+question/191211

hello,

I try to modify the feedback system. I mainly change three files : 
rohc_decomp.h/c and d_generic.c. I set the situation "ROHC_ERROR" to 
"ROHC_ERROR_CRC", ie, if decompression is failure, it always returns 
ROHC_ERROR_CRC. I change feedback from piggybacking to interspersing. So I add 
ROHC_ERROR_FEEDBACK when feedback is decompressed unsuccessfully.
Here are the main code:

first, in file rohc_decomp.h
add #define N and #define K

in struct d_context add:
/// create a window for feedback interval in NO CONTEXT state
    struct c_wlsb *curvalnc;
    /// create a window for feedback interval in STATIC CONTEXT state
    struct c_wlsb *curvalsc;
    /// create a window for feedback interval in FULL CONTEXT state
    struct c_wlsb *curvalfc;
    /// create a window for feedback interval in case of ROHC_ERROR_NO_CONTEXT
    struct c_wlsb *curvalenc;
     /// create a window for feedback interval in STATIC CONTEXT state
    struct c_wlsb *curvalsc0;
    ///The number of received packets in NO CONTEXT state
    int num_recv_nc;
    ///The number of received packets in STATIC CONTEXT state
    int num_recv_sc;
    ///The number of received packets in FULL CONTEXT state
    int num_recv_fc;
    ///The number of received packets in case of ROHC_ERROR_CONTEXT
    int num_recv_enc;
    ///The number of received packets in STATIC CONTEXT state(type0,1)
    int num_recv_sc0;

second, in file  rohc_decomp.c 
in function rohc_decompress():
switch(ret)
        {
        case ROHC_ERROR_PACKET_FAILED:
        break;
        //BY SQ
        case ROHC_ERROR_FEEDBACK:
        break;
        case ROHC_ERROR_CRC:
            decomp->statistics.packets_failed_crc++;
            switch(ddata.active->state)
            {
            case NO_CONTEXT:
                ddata.active->num_recv_nc++;
                rohc_debugf(2, "num_recv_nc = %d\n", ddata.active->num_recv_nc);
                c_add_wlsb(ddata.active->curvalnc, 0, 0, 1);
                if(ddata.active->num_recv_nc >= N && 
c_sum_wlsb(ddata.active->curvalnc)>= K &&
                   c_sum_wlsb(ddata.active->curvalnc) <= N) 
                {
                    int i;
                    //set wlsb window value to zero 
                    for(i = 0; i < N; i++) 
                    {
                        c_add_wlsb(ddata.active->curvalnc, 0, 0, 0);
                        ddata.active->curvalnc->next--;
                        
ddata.active->curvalnc->window[ddata.active->curvalnc->next].used = ROHC_FALSE;
                        ddata.active->curvalnc->next++;
                    }
                    ddata.active->curvalnc->next = 0;
                    ddata.active->curvalnc->oldest = 0;
                    ddata.active->num_recv_nc = 0;

                    rohc_debugf(2, "feedback curr %d\n", 
c_sum_wlsb(ddata.active->curvalnc));
                                rohc_debugf(2, "feedback max %d  no context\n", 
N);
                    d_operation_mode_feedback(decomp, ROHC_ERROR_CRC, ddata.cid,
                                                          ddata.addcidUsed, 
ddata.largecidUsed,
                                                          ddata.active->mode, 
ddata.active);
                }
                break;
            case STATIC_CONTEXT:
                ddata.active->num_recv_sc++;
                rohc_debugf(2, "num_recv_sc = %d\n", ddata.active->num_recv_sc);
                c_add_wlsb(ddata.active->curvalsc, 0, 0, 1);
                if(ddata.active->num_recv_sc >= N && 
c_sum_wlsb(ddata.active->curvalsc)>= K &&
                   c_sum_wlsb(ddata.active->curvalsc) <= N) 
                {   
                    int i;
                    //set wlsb window value to zero 
                    for(i = 0; i < N; i++) 
                    {
                        c_add_wlsb(ddata.active->curvalsc, 0, 0, 0);
                        ddata.active->curvalsc->next--;
                        
ddata.active->curvalsc->window[ddata.active->curvalsc->next].used = ROHC_FALSE;
                        ddata.active->curvalsc->next++;
                    }
                    ddata.active->curvalsc->next = 0;
                    ddata.active->curvalsc->oldest = 0;
                    ddata.active->num_recv_sc = 0;

                    rohc_debugf(2, "feedback curr %d\n", 
c_sum_wlsb(ddata.active->curvalsc));
                                rohc_debugf(2, "feedback max %d  static context 
%d\n", N);
                    d_operation_mode_feedback(decomp, ROHC_ERROR_CRC, ddata.cid,
                                                          ddata.addcidUsed, 
ddata.largecidUsed,
                                                          ddata.active->mode, 
ddata.active);
                }
                break;
            case FULL_CONTEXT:
                ddata.active->num_recv_fc++;
                rohc_debugf(2, "num_recv_fc = %d\n", ddata.active->num_recv_fc);
                c_add_wlsb(ddata.active->curvalfc, 0, 0, 1);
                if(ddata.active->num_recv_fc >= N && 
c_sum_wlsb(ddata.active->curvalfc)>= K &&
                   c_sum_wlsb(ddata.active->curvalfc) <= N) 
                {   
                    int i;
                    //set wlsb window value to zero 
                    for(i = 0; i < N; i++) 
                    {
                        c_add_wlsb(ddata.active->curvalfc, 0, 0, 0);
                        ddata.active->curvalfc->next--;
                        
ddata.active->curvalfc->window[ddata.active->curvalfc->next].used = ROHC_FALSE;
                        ddata.active->curvalfc->next++;
                    }
                    ddata.active->curvalfc->next = 0;
                    ddata.active->curvalfc->oldest = 0;
                    ddata.active->num_recv_fc = 0;

                    rohc_debugf(2, "feedback curr %d\n", 
c_sum_wlsb(ddata.active->curvalfc));
                                rohc_debugf(2, "feedback max %d  full 
context\n", N);
                    d_operation_mode_feedback(decomp, ROHC_ERROR_CRC, ddata.cid,
                                                          ddata.addcidUsed, 
ddata.largecidUsed,
                                                          ddata.active->mode, 
ddata.active);
                }
                break;

            }

                case ROHC_ERROR_NO_CONTEXT:
                        decomp->statistics.packets_failed_no_context++;
            ddata.active->num_recv_enc++;
            rohc_debugf(2, "num_recv_enc = %d\n", ddata.active->num_recv_enc);
            c_add_wlsb(ddata.active->curvalenc, 0, 0, 1);
            if(ddata.active->num_recv_enc >= N && 
c_sum_wlsb(ddata.active->curvalenc)>= K &&
            c_sum_wlsb(ddata.active->curvalenc) <= N) 
            {   
                int i;
                //set wlsb window value to zero 
                for(i = 0; i < N; i++) 
                {
                    c_add_wlsb(ddata.active->curvalenc, 0, 0, 0);
                    ddata.active->curvalenc->next--;
                    
ddata.active->curvalenc->window[ddata.active->curvalenc->next].used = 
ROHC_FALSE;
                    ddata.active->curvalenc->next++;
                }
                ddata.active->curvalenc->next = 0;
                ddata.active->curvalenc->oldest = 0;
                ddata.active->num_recv_enc = 0;

                rohc_debugf(2, "feedback curr %d\n", 
c_sum_wlsb(ddata.active->curvalenc));
                            rohc_debugf(2, "feedback max %d  error no 
context\n", N);
                d_operation_mode_feedback(decomp, ROHC_ERROR_NO_CONTEXT, 
ddata.cid,
                                                          ddata.addcidUsed, 
ddata.largecidUsed,
                                                          O_MODE, NULL);
                }
                        break;
        
        case ROHC_ERROR_SC:
                        ddata.active->num_recv_sc0++;
            rohc_debugf(2, "num_recv_sc0 = %d\n", ddata.active->num_recv_sc0);
            c_add_wlsb(ddata.active->curvalsc0, 0, 0, 1);
            if(ddata.active->num_recv_sc0 >= N && 
c_sum_wlsb(ddata.active->curvalsc0)>= K &&
            c_sum_wlsb(ddata.active->curvalsc0) <= N) 
            {   
                int i;
                //set wlsb window value to zero 
                for(i = 0; i < N; i++) 
                {
                    c_add_wlsb(ddata.active->curvalsc0, 0, 0, 0);
                    ddata.active->curvalsc0->next--;
                    
ddata.active->curvalsc0->window[ddata.active->curvalsc0->next].used = 
ROHC_FALSE;
                    ddata.active->curvalsc0->next++;
                }
                ddata.active->curvalsc0->next = 0;
                ddata.active->curvalsc0->oldest = 0;
                ddata.active->num_recv_sc0 = 0;

                rohc_debugf(2, "feedback curr %d\n", 
c_sum_wlsb(ddata.active->curvalsc0));
                            rohc_debugf(2, "feedback max %d  sc(recieve 
type1,0)\n", N);
                d_operation_mode_feedback(decomp, ROHC_ERROR_NO_CONTEXT, 
ddata.cid,
                                                          ddata.addcidUsed, 
ddata.largecidUsed,
                                                          O_MODE, NULL);
                }
                        break;

                default:        /* ROHC_OK_NO_DATA, ROHC_OK */
                        if(decomp->compressor != NULL && decomp->ack_sent < 
MAX_ACK)
                        {
                                /* switch active context to O-mode */
                                ddata.active->mode = O_MODE;
                                d_operation_mode_feedback(decomp, ROHC_OK, 
ddata.cid, ddata.addcidUsed,
                                                          ddata.largecidUsed, 
ddata.active->mode,
                                                          ddata.active);
                decomp->ack_sent++;
                rohc_debugf(2, "the number of transition ack is %d\n", 
decomp->ack_sent);
                        }
                        break;
        }

in function d_optimistic_feedback():
switch(rohc_status)
        {
                case ROHC_OK:
                        /* create an ACK feedback */
                        rohc_debugf(1, "send an ACK feedback\n");
                        f_feedback2(ACKTYPE_ACK, context->mode, 
context->profile->get_sn(context), &sfeedback);
                        feedback = f_wrap_feedback(&sfeedback, cid, 
largecidUsed, WITH_CRC, &feedbacksize);
                        if(feedback == NULL)
                        {
                                rohc_debugf(0, "failed to create an ACK 
feedback\n");
                                return;
                        }

                        /* send the feedback via the compressor associated
                         * with the decompressor */
                        context->num_sent_feedbacks++;
                        c_piggyback_feedback(decomp->compressor, feedback, 
feedbacksize);

                        /* destroy the feedback */
                        zfree(feedback);
                        break;

                case ROHC_ERROR_NO_CONTEXT:
                        /* create a STATIC NACK feedback */
                        rohc_debugf(1, "send a STATIC NACK feedback\n");
                        f_feedback2(ACKTYPE_STATIC_NACK, O_MODE, 0, &sfeedback);
                        f_add_option(&sfeedback, OPT_TYPE_SN_NOT_VALID, NULL);
                        feedback = f_wrap_feedback(&sfeedback, cid, 
largecidUsed, NO_CRC, &feedbacksize);
                        if(feedback == NULL)
                        {
                                rohc_debugf(0, "failed to create a STATIC NACK 
feedback\n");
                                return;
                        }

                        /* send the feedback via the compressor associated
                         * with the decompressor */
                        context->num_sent_feedbacks++;
                        c_piggyback_feedback(decomp->compressor, feedback, 
feedbacksize);

                        /* destroy the feedback */
                        zfree(feedback);
                        break;

        case ROHC_ERROR_SC:
            if(context->state != STATIC_CONTEXT) 
            {
               return;
            }
            /* create a NACK feedback */
                        rohc_debugf(1, "send a NACK feedback\n");
                        f_feedback2(ACKTYPE_NACK, context->mode, 
context->profile->get_sn(context), &sfeedback);
                        feedback = f_wrap_feedback(&sfeedback, cid, 
largecidUsed, WITH_CRC, &feedbacksize);
                        if(feedback == NULL)
                        {
                            rohc_debugf(0, "failed to create a NACK 
feedback\n");
                            return;
                        }

                        /* send the feedback via the compressor associated
                         * with the decompressor */
            context->num_sent_feedbacks++;
                    c_piggyback_feedback(decomp->compressor, feedback, 
feedbacksize);

                        /* destroy the feedback */
                    zfree(feedback);
            break;

                case ROHC_ERROR_CRC:
                        //context->num_sent_feedbacks++;
                        switch(context->state)
                        {
                                case NO_CONTEXT:
                                        /* create a STATIC NACK feedback */
                                        rohc_debugf(1, "send a STATIC NACK 
feedback\n");
                                        f_feedback2(ACKTYPE_STATIC_NACK, 
context->mode, context->profile->get_sn(context), &sfeedback);
                                        feedback = f_wrap_feedback(&sfeedback, 
cid, largecidUsed, WITH_CRC, &feedbacksize);
                                        if(feedback == NULL)
                                        {
                                                rohc_debugf(0, "failed to 
create a STATIC NACK feedback\n");
                                                return;
                                        }

                                        /* send the feedback via the compressor 
associated
                                         * with the decompressor */
                    context->num_sent_feedbacks++; 
                                        
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);

                                        /* destroy the feedback */
                                        zfree(feedback);
                                        break;

            case STATIC_CONTEXT:
                     /* create a STATIC NACK feedback*/
                    rohc_debugf(1, "send a STATIC NACK feedback\n");
                                        f_feedback2(ACKTYPE_STATIC_NACK, 
context->mode, context->profile->get_sn(context), &sfeedback);
                                        feedback = f_wrap_feedback(&sfeedback, 
cid, largecidUsed, WITH_CRC, &feedbacksize);
                                        if(feedback == NULL)
                                        {
                                                rohc_debugf(0, "failed to 
create a STATIC NACK feedback\n");
                                                return;
                                        }

                                        /* send the feedback via the compressor 
associated
                                         * with the decompressor */
                    context->num_sent_feedbacks++;
                                        
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);

                    /* change state */
                    rohc_debugf(1, "change decompressor state from SC to NC");
                    context->state = NO_CONTEXT;

                    /* destroy the feedback */
                                        zfree(feedback);
                    break;

                                case FULL_CONTEXT:
                                        /* create a NACK feedback */
                                        rohc_debugf(1, "send a NACK 
feedback\n");
                                        f_feedback2(ACKTYPE_NACK, 
context->mode, context->profile->get_sn(context), &sfeedback);
                                        feedback = f_wrap_feedback(&sfeedback, 
cid, largecidUsed, WITH_CRC, &feedbacksize);
                                        if(feedback == NULL)
                                        {
                                                rohc_debugf(0, "failed to 
create a NACK feedback\n");
                                                return;
                                        }

                                        /* send the feedback via the compressor 
associated
                                         * with the decompressor */
                    context->num_sent_feedbacks++;
                                        
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);

                                        /* change state */
                    rohc_debugf(1, "change decompressor state from FC to SC");
                                        context->state = STATIC_CONTEXT;

                                        /* destroy the feedback */
                                        zfree(feedback);
                                        break;

                                default:
                                        rohc_debugf(0, "should not arrive: 
unknown state value (%d)\n",
                                                    context->state);
                                        break;
                        }
                        break;
        }

in function struct d_context * context_create():
 context->num_recv_nc = 0;
    context->num_recv_sc = 0;
    context->num_recv_fc = 0;
    context->num_recv_enc = 0;
    context->num_recv_sc0 = 0;
    context->curvalnc = c_create_wlsb(32, N, 0);
    context->curvalsc = c_create_wlsb(32, N, 0);
    context->curvalfc = c_create_wlsb(32, N, 0);
    context->curvalenc = c_create_wlsb(32, N, 0);
    context->curvalsc0 = c_create_wlsb(32, N, 0);

in function context_free():
c_destroy_wlsb(context->curvalnc);
        c_destroy_wlsb(context->curvalsc);
        c_destroy_wlsb(context->curvalfc);
        c_destroy_wlsb(context->curvalenc);
        c_destroy_wlsb(context->curvalsc0);

third, in file d_generic.c
in function decode_generic_decode_ir(), add code before context->state = 
FULL_CONTEXT:
//set wlsb window value to zero when change state
if(context->state == NO_CONTEXT)
        {
            int i;
            //set wlsb window value to zero 
            for(i = 0; i < N; i++) 
            {
                c_add_wlsb(context->curvalnc, 0, 0, 0);
                context->curvalnc->next--;
                context->curvalnc->window[context->curvalnc->next].used = 
ROHC_FALSE;
                context->curvalnc->next++;
            }
            context->curvalnc->next = 0;
            context->curvalnc->oldest = 0;
            context->num_recv_nc = 0;
        }
        else if(context->state == STATIC_CONTEXT)
        {
             int i;
            //set wlsb window value to zero 
            for(i = 0; i < N; i++) 
            {
                c_add_wlsb(context->curvalsc, 0, 0, 0);
                context->curvalsc->next--;
                context->curvalsc->window[context->curvalsc->next].used = 
ROHC_FALSE;
                context->curvalsc->next++;
                c_add_wlsb(context->curvalsc0, 0, 0, 0);
                context->curvalsc0->next--;
                context->curvalsc0->window[context->curvalsc0->next].used = 
ROHC_FALSE;
                context->curvalsc0->next++;
            }
            context->curvalsc->next = 0;
            context->curvalsc->oldest = 0;
            context->num_recv_sc = 0;
            context->curvalsc0->next = 0;
            context->curvalsc0->oldest = 0;
            context->num_recv_sc0 = 0;
        }

in function decode_irdyn, add code after context->state = FULL_CONTEXT:
int i1;
    //set wlsb window value to zero when change state
    for(i1 = 0; i1 < N; i1++) 
    {
         c_add_wlsb(context->curvalsc, 0, 0, 0);
         context->curvalsc->next--;
         context->curvalsc->window[context->curvalsc->next].used = ROHC_FALSE;
         context->curvalsc->next++;
         c_add_wlsb(context->curvalsc0, 0, 0, 0);
         context->curvalsc0->next--;
         context->curvalsc0->window[context->curvalsc0->next].used = ROHC_FALSE;
         context->curvalsc0->next++;
    }
    context->curvalsc->next = 0;
    context->curvalsc->oldest = 0;
    context->num_recv_sc = 0;
    context->curvalsc0->next = 0;
    context->curvalsc0->oldest = 0;
    context->num_recv_sc0 = 0;

in function decode_uor2(), add code after context->state = FULL_CONTEXT:
int i1;
    //set wlsb window value to zero when change state
    for(i1 = 0; i1 < N; i1++) 
    {
         c_add_wlsb(context->curvalsc, 0, 0, 0);
         context->curvalsc->next--;
         context->curvalsc->window[context->curvalsc->next].used = ROHC_FALSE;
         context->curvalsc->next++;
         c_add_wlsb(context->curvalsc0, 0, 0, 0);
         context->curvalsc0->next--;
         context->curvalsc0->window[context->curvalsc0->next].used = ROHC_FALSE;
         context->curvalsc0->next++;
    }
    context->curvalsc->next = 0;
    context->curvalsc->oldest = 0;
    context->num_recv_sc = 0;
    context->curvalsc0->next = 0;
    context->curvalsc0->oldest = 0;
    context->num_recv_sc0 = 0;

in function d_generic_decode:
 in switch(find_packet_type(decomp, context, packet, second_byte)): case 
PACKET_UO_0, case PACKET_UO_1, case PACKET_UO_1_ID, change "goto error" to 
"return ROHC_ERROR_SC".

I change the code in that way according to RFC 3095 5.3.2.2.3 and 5.4.2.2.
 




-- 
You received this question notification because you are a member of ROHC
Team, which is an answer contact for rohc.

_______________________________________________
Mailing list: https://launchpad.net/~rohc
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~rohc
More help   : https://help.launchpad.net/ListHelp

Reply via email to