Beispiel #1
0
void send_datagram (struct NLS_HandleTypedef* hNLS , uint8_t* packet , int length , datagram_address_t dest_address , datagram_qos_t qos , uint8_t retry)
{
	if(retry != 0)
	{

		downStreamTablePenaliziesBestPath(hNLS->dTable , dest_address);
	}

	//lookup downstream table
	datagram_if_id_t dspath[MAX_HOP_COUNT];
	uint8_t ds_path_len;


	if(downstreamTableGetBestPath(hNLS->dTable , dest_address ,dspath , &ds_path_len )==1){
		printf("IMPOSSIBILE INVIARE _ NO BEST PATH PER %x \n\r",dest_address);
		return;
	}

	//printf(" dspath[0] : %d , dspath[1] : %d \n\r" , dspath[0] , dspath[1]);

	//costruisci un pacchetto downstream

	dsData_typedef data;
	data.address = dest_address;
	data.qos = qos;
	data.ds_path = dspath;
	data.ds_path_length = ds_path_len;
	data.payload_length = length;
	data.payload = packet;
	data.trailer = trailer_gen(packet , length);

	int datagram_len;
	uint8_t* to_send = build_dsData(data , &datagram_len);
//	printf("PACCHETTO DOWNSTREAM \n\r");
//
//	print_dsData(to_send);
	//costruisci struttura datagram info
	datagram_info* d_info = init_datagram_info(to_send , NO_SRC_IF , datagram_len, 0);

	//invia
	send_downstream(hNLS , d_info);

}
/**
 *  Funzione eseguita ciclicamente. Disaccoda un pacchetto, ne verifica il tipo
 *  ed chiama la primitiva di invio appropriata.
 */
void dispatch (struct NLS_HandleTypedef* hNLS)   //XXX PER PAOLO: MODIFICA FATTA!!
{
	//scoda la prep queue se vuota
	if (!simpleQueueEmpty(hNLS->PREP_queue))
	{
		//TODO Log
		//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
		//							LOG_STRING, "scoda la coda PREP", "OK",
		//							LOG_END);

		on_PREP(hNLS , simpleQueueDequeue(hNLS->PREP_queue));
	}

	//scoda la coda di ingresso
	datagram_info* d_info = (datagram_info*)priorityQueueDequeue(hNLS->routing_queue);

	if (d_info == NULL)
	{
		//TODO Log
		//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
		//							LOG_STRING, "scoda la coda d'ingresso", "OK",
		//							LOG_STRING, "coda d'ingresso", "nessun datagram",
		//							LOG_END);

		return;
	}

	//TODO Log
	//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
	//							LOG_STRING, "scoda la coda d'ingresso", "OK",
	//							LOG_STRING, "coda d'ingresso", "datagram scodato",
	//							LOG_INT, "if source", d_info->source_if,
	//							LOG_INT, "datagram type", d_info->type,
	//							LOG_INT, "packet length", d_info->packet_length,
	//							LOG_INT, "address", d_info->address,
	//							LOG_END);


	//i messaggi di upstream e downstream diretti al root vanno direttamente al livello superiore
#ifdef ROOT
	if (d_info->type == DATA_UP) //XXX CONTROLLARE DATA_DOWN
	{

		//TODO Log
		//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
		//							LOG_STRING, "nodo ROOT: datagram type", "DATA UP",
		//							LOG_STRING, "nodo ROOT: trasferisci al livello superiore", "OK",
		//							LOG_END);

		on_datagram_received(d_info);
		return;
	}
#else
	if ((get_datagram_address(d_info->packet) == MY_ADDRESS) && (d_info->type == DATA_DOWN))
	{
		//è un datagramma dati, manda ai livelli superiori

		//TODO Log
		//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
		//							LOG_STRING, "datagram dati", "trasferisci aL livellO superiorE",
		//							LOG_END);

		on_datagram_received(d_info);
		//BSP_LED_On(LED5);
		return;
	}


	//se non ho un path
	if(UTGetSize(hNLS->uTable) == 0)
	{
		//se non ho un path ma  ho pacchetti da inviare
		if(d_info != NULL)
		{

			//fai path discovery

			//TODO Log
			//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch",
			//							LOG_STRING, "nessun path e datagram da inviare", "esegui path discovery",
			//							LOG_END);

			on_path_discovery(hNLS , d_info);

		}

	}
#endif


	//qui sono associato
	switch(d_info->type)
	{

	case DATA_UP:
	{
#ifndef ROOT   //XXX PER PAOLO: Attenzione a questo #ifndef; potrebbe anche non essere necessario
		if(d_info->source_if == UTGetMainLink(hNLS->uTable))
		{

			//TODO Log
			//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
			//							LOG_STRING, "datagram type", "DATA UP",
			//							LOG_STRING, "swap main link in Upstream Table", "OK",
			//							LOG_END);

			UTSwapMainLink(hNLS->uTable);
		}

		send_upstream(hNLS , d_info);
#endif
		break;

	}
	case DATA_DOWN:
	{

		//TODO Log
		//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
		//							LOG_STRING, "datagram type", "DATA DOWN",
		//							LOG_STRING, "trasmissione DOWNSTREAM", "OK",
		//							LOG_END);

		send_downstream(hNLS , d_info);
		break;

	}
	case BSRP_PREQ:
	{
#ifndef ROOT
		if(hNLS->enabled_ifs_num!=1)  //XXX ZUPPA PAOLO: TENTATIVO DI AGGIUSTARE IL PROTOCOLLO
#endif

			//TODO Log
			//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
			//							LOG_STRING, "datagram type", "PREQ",
			//							LOG_STRING, "on PREQ", "OK",
			//							LOG_END);

			on_PREQ(hNLS  , d_info);

		break;
	}
	case BSRP_PFWD:
	{

		//TODO Log
		//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
		//							LOG_STRING, "datagram type", "PFWD",
		//							LOG_STRING, "on PFWD", "OK",
		//							LOG_END);

		on_PFWD(hNLS , d_info);
		break;
	}
	case BSRP_PREP:
	{
#ifndef ROOT

		//TODO Log
		//EventLogger_LogEvent(&LOG_HANDLE, NETWORK, NOTICE, MY_ADDRESS, "dispatch()",
		//							LOG_STRING, "datagram type", "PREP",
		//							LOG_STRING, "trasmissione DOWNSTREAM", "OK",
		//							LOG_END);

		send_downstream(hNLS  , d_info);
#endif
		break;

	}
	case BSRP_PACK:
	{
		break;
	}
	}


}
Beispiel #3
0
/* xlate_out_filter() handles (almost) arbitrary conversions from one charset
 * to another...
 * translation is determined in the fixup hook (find_code_page), which is
 * where the filter's context data is set up... the context data gives us
 * the translation handle
 */
static apr_status_t xlate_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    charset_req_t *reqinfo = ap_get_module_config(f->r->request_config,
                                                  &charset_lite_module);
    charset_dir_t *dc = ap_get_module_config(f->r->per_dir_config,
                                             &charset_lite_module);
    charset_filter_ctx_t *ctx = f->ctx;
    apr_bucket *dptr, *consumed_bucket;
    const char *cur_str;
    apr_size_t cur_len, cur_avail;
    char tmp[OUTPUT_XLATE_BUF_SIZE];
    apr_size_t space_avail;
    int done;
    apr_status_t rv = APR_SUCCESS;

    if (!ctx) {
        /* this is SetOutputFilter path; grab the preallocated context,
         * if any; note that if we decided not to do anything in an earlier
         * handler, we won't even have a reqinfo
         */
        if (reqinfo) {
            ctx = f->ctx = reqinfo->output_ctx;
            reqinfo->output_ctx = NULL; /* prevent SNAFU if user coded us twice
                                         * in the filter chain; we can't have two
                                         * instances using the same context
                                         */
        }
        if (!ctx) {                   /* no idea how to translate; don't do anything */
            ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(charset_filter_ctx_t));
            ctx->dc = dc;
            ctx->noop = 1;
        }
    }

    /* Check the mime type to see if translation should be performed.
     */
    if (!ctx->noop && ctx->xlate == NULL) {
        const char *mime_type = f->r->content_type;

        if (mime_type && (strncasecmp(mime_type, "text/", 5) == 0 ||
#if APR_CHARSET_EBCDIC
        /* On an EBCDIC machine, be willing to translate mod_autoindex-
         * generated output.  Otherwise, it doesn't look too cool.
         *
         * XXX This isn't a perfect fix because this doesn't trigger us
         * to convert from the charset of the source code to ASCII.  The
         * general solution seems to be to allow a generator to set an
         * indicator in the r specifying that the body is coded in the
         * implementation character set (i.e., the charset of the source
         * code).  This would get several different types of documents
         * translated properly: mod_autoindex output, mod_status output,
         * mod_info output, hard-coded error documents, etc.
         */
            strcmp(mime_type, DIR_MAGIC_TYPE) == 0 ||
#endif
            strncasecmp(mime_type, "message/", 8) == 0 ||
            dc->force_xlate == FX_FORCE)) {

            rv = apr_xlate_open(&ctx->xlate,
                                dc->charset_default, dc->charset_source, f->r->pool);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(01453)
                              "can't open translation %s->%s",
                              dc->charset_source, dc->charset_default);
                ctx->noop = 1;
            }
            else {
                if (apr_xlate_sb_get(ctx->xlate, &ctx->is_sb) != APR_SUCCESS) {
                    ctx->is_sb = 0;
                }
            }
        }
        else {
            ctx->noop = 1;
            if (mime_type) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE6, 0, f->r,
                              "mime type is %s; no translation selected",
                              mime_type);
            }
        }
    }

    ap_log_rerror(APLOG_MARK, APLOG_TRACE6, 0, f->r,
                  "xlate_out_filter() - "
                  "charset_source: %s charset_default: %s",
                  dc && dc->charset_source ? dc->charset_source : "(none)",
                  dc && dc->charset_default ? dc->charset_default : "(none)");

    if (!ctx->ran) {  /* filter never ran before */
        chk_filter_chain(f);
        ctx->ran = 1;
        if (!ctx->noop && !ctx->is_sb) {
            /* We're not converting between two single-byte charsets, so unset
             * Content-Length since it is unlikely to remain the same.
             */
            apr_table_unset(f->r->headers_out, "Content-Length");
        }
    }

    if (ctx->noop) {
        return ap_pass_brigade(f->next, bb);
    }

    dptr = APR_BRIGADE_FIRST(bb);
    done = 0;
    cur_len = 0;
    space_avail = sizeof(tmp);
    consumed_bucket = NULL;
    while (!done) {
        if (!cur_len) { /* no bytes left to process in the current bucket... */
            if (consumed_bucket) {
                apr_bucket_delete(consumed_bucket);
                consumed_bucket = NULL;
            }
            if (dptr == APR_BRIGADE_SENTINEL(bb)) {
                break;
            }
            if (APR_BUCKET_IS_EOS(dptr)) {
                cur_len = -1; /* XXX yuck, but that tells us to send
                                 * eos down; when we minimize our bb construction
                                 * we'll fix this crap */
                if (ctx->saved) {
                    /* Oops... we have a partial char from the previous bucket
                     * that won't be completed because there's no more data.
                     */
                    rv = APR_INCOMPLETE;
                    ctx->ees = EES_INCOMPLETE_CHAR;
                }
                break;
            }
            if (APR_BUCKET_IS_METADATA(dptr)) {
                apr_bucket *metadata_bucket;
                metadata_bucket = dptr;
                dptr = APR_BUCKET_NEXT(dptr);
                APR_BUCKET_REMOVE(metadata_bucket);
                rv = send_bucket_downstream(f, metadata_bucket);
                if (rv != APR_SUCCESS) {
                    done = 1;
                }
                continue;
            }
            rv = apr_bucket_read(dptr, &cur_str, &cur_len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                ctx->ees = EES_BUCKET_READ;
                break;
            }
            consumed_bucket = dptr; /* for axing when we're done reading it */
            dptr = APR_BUCKET_NEXT(dptr); /* get ready for when we access the
                                          * next bucket */
        }
        /* Try to fill up our tmp buffer with translated data. */
        cur_avail = cur_len;

        if (cur_len) { /* maybe we just hit the end of a pipe (len = 0) ? */
            if (ctx->saved) {
                /* Rats... we need to finish a partial character from the previous
                 * bucket.
                 */
                char *tmp_tmp;

                tmp_tmp = tmp + sizeof(tmp) - space_avail;
                rv = finish_partial_char(ctx,
                                         &cur_str, &cur_len,
                                         &tmp_tmp, &space_avail);
            }
            else {
                rv = apr_xlate_conv_buffer(ctx->xlate,
                                           cur_str, &cur_avail,
                                           tmp + sizeof(tmp) - space_avail, &space_avail);

                /* Update input ptr and len after consuming some bytes */
                cur_str += cur_len - cur_avail;
                cur_len = cur_avail;

                if (rv == APR_INCOMPLETE) { /* partial character at end of input */
                    /* We need to save the final byte(s) for next time; we can't
                     * convert it until we look at the next bucket.
                     */
                    rv = set_aside_partial_char(ctx, cur_str, cur_len);
                    cur_len = 0;
                }
            }
        }

        if (rv != APR_SUCCESS) {
            /* bad input byte or partial char too big to store */
            done = 1;
        }

        if (space_avail < XLATE_MIN_BUFF_LEFT) {
            /* It is time to flush, as there is not enough space left in the
             * current output buffer to bother with converting more data.
             */
            rv = send_downstream(f, tmp, sizeof(tmp) - space_avail);
            if (rv != APR_SUCCESS) {
                done = 1;
            }

            /* tmp is now empty */
            space_avail = sizeof(tmp);
        }
    }

    if (rv == APR_SUCCESS) {
        if (space_avail < sizeof(tmp)) { /* gotta write out what we converted */
            rv = send_downstream(f, tmp, sizeof(tmp) - space_avail);
        }
    }
    if (rv == APR_SUCCESS) {
        if (cur_len == -1) {
            rv = send_eos(f);
        }
    }
    else {
        log_xlate_error(f, rv);
    }

    return rv;
}