← Back to team overview

rohc team mailing list archive

[Question #191211]: modify the feedback system in O-mode

 

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.