int main(void) {
    pid_t pid;
    int i, j;
    
    start_sync();
    
    if ((pid=fork()) < 0) {
        perror("fork()");
        return EXIT_FAILURE;
    }
    else if (pid == 0) {
        for (i = 0; i < MAX; ++i) {
            kind_wartet();
            printf("Kind \n");
            kind2eltern(getppid());
        }
        
        printf("--- Kind Ende ---\n");
        exit(EXIT_SUCCESS);
    }
    
    for (j = 0; j < MAX; ++j) {
        printf("Eltern \n");
        eltern2kind(pid);
        eltern_warten();
    }
    
    printf("-- Eltern Ende ---\n");
    return EXIT_SUCCESS;
}
Exemple #2
0
static uint32_t get_global_time(func_cb_ptr p, uint32_t time) {
    app_state_t* s = (app_state_t*)sys_get_state();

    if(s->sync_state == SYNCED || s->sync_state == SYNCING) {
        // we are synced, and thus had at least one time sync exchange
        // if we are level 1, then just return our time
        if(s->level == 1) {
            return time;
        } else {
            uint32_t delta_refresh = 0;
            uint32_t cur_time = sys_time32();
            // check for overflow
            if(cur_time < s->last_refresh) {
                cur_time += 0x7F000000;
            }
            delta_refresh = cur_time - s->last_refresh;
            // only try to refresh if we are not already syncing.
            if (s->sync_state == SYNCED && delta_refresh > REFRESH_INTERVAL) {
                DEBUG("TPSN_NET: Refresh needed refresh: %d\n", delta_refresh);
                s->sync_state = SYNCING;

                start_sync();
            }
            // even though we might be syncing, reply with the current estimate.
            return time + s->clock_drift;
        }
    } else {
        return NOT_SYNCED;
    }

}
static void start_rach(void)
{
	struct gsm48_sysinfo *s = &sysinfo;
	uint8_t chan_req_val, chan_req_mask;
	struct msgb *nmsg;
	struct abis_rsl_cchan_hdr *ncch;

	if (rach_count == RACH_MAX) {
		log_sysinfo();
		start_sync();
		return;
	}

	state = SCAN_STATE_RACH;

	if (s->neci) {
		chan_req_mask = 0x0f;
		chan_req_val = 0x01;
		LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
			"(OTHER with NECI)\n", chan_req_val);
	} else {
		chan_req_mask = 0x1f;
		chan_req_val = 0xe0;
		LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OTHER no NECI)\n",
			chan_req_val);
	}

	rach_ref.valid = 0;
	rach_ref.cr = random();
	rach_ref.cr &= chan_req_mask;
	rach_ref.cr |= chan_req_val;

	nmsg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
		RSL_ALLOC_HEADROOM, "GSM 04.06 RSL");
	if (!nmsg)
		return;
	nmsg->l2h = nmsg->data;
	ncch = (struct abis_rsl_cchan_hdr *) msgb_put(nmsg, sizeof(*ncch)
							+ 4 + 2 + 2);
	rsl_init_cchan_hdr(ncch, RSL_MT_CHAN_RQD);
	ncch->chan_nr = RSL_CHAN_RACH;
	ncch->data[0] = RSL_IE_REQ_REFERENCE;
	ncch->data[1] = rach_ref.cr;
	ncch->data[2] = (s->ccch_conf == 1) << 7;
	ncch->data[3] = 0;
	ncch->data[4] = RSL_IE_ACCESS_DELAY;
	ncch->data[5] = 0; /* no delay */ 
	ncch->data[6] = RSL_IE_MS_POWER;
	ncch->data[7] = 0; /* full power */

	start_timer(RACH_WAIT);

	lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
}
static int signal_cb(unsigned int subsys, unsigned int signal,
		     void *handler_data, void *signal_data)
{
	struct osmobb_meas_res *mr;
	struct osmobb_fbsb_res *fr;
	uint16_t index;

	if (subsys != SS_L1CTL)
		return 0;

	switch (signal) {
	case S_L1CTL_PM_RES:
		mr = signal_data;
		index = mr->band_arfcn & 0x3ff;
		pm[index].flags |= INFO_FLG_PM;
		pm[index].rxlev = mr->rx_lev - 110;
		if (pm[index].rxlev >= min_rxlev)
			sync_count++;
//		printf("rxlev %d = %d (sync_count %d)\n", index, pm[index].rxlev, sync_count);
		break;
	case S_L1CTL_PM_DONE:
		pm_index++;
		start_pm();
		break;
	case S_L1CTL_FBSB_RESP:
		fr = signal_data;
		sysinfo.bsic = fr->bsic;
		state = SCAN_STATE_READ;
		memset(&ms->meas, 0, sizeof(ms->meas));
		memset(&log_si, 0, sizeof(log_si));
		log_si.flags |= INFO_FLG_SYNC;
		log_si.ta = 0xff; /* invalid */
		start_timer(READ_WAIT);
		LOGP(DRR, LOGL_INFO, "Synchronized, start reading\n");
		break;
	case S_L1CTL_FBSB_ERR:
		LOGP(DRR, LOGL_INFO, "Sync failed\n");
		start_sync();
		break;
	case S_L1CTL_RESET:
		if (started)
			break;
		started = 1;
		memset(pm, 0, sizeof(pm));
		pm_index = 0;
		sync_count = 0;
		start_pm();
	}
	return 0;
}
static void timeout_cb(void *arg)
{
	switch (state) {
	case SCAN_STATE_READ:
		LOGP(DRR, LOGL_INFO, "Timeout reading BCCH\n");
		start_sync();
		break;
	case SCAN_STATE_RACH:
		LOGP(DRR, LOGL_INFO, "Timeout on RACH\n");
		rach_count++;
		start_rach();
		break;
	}
}
static int ta_result(uint8_t ta)
{
	stop_timer();

	if (ta == 0xff)
		LOGP(DSUM, LOGL_INFO, "Got assignment reject\n");
	else {
		LOGP(DSUM, LOGL_DEBUG, "Got assignment TA = %d\n", ta);
		log_si.ta = ta;
	}

	log_sysinfo();
	start_sync();

	return 0;
}
void dal_i2c_sw_engine_submit_channel_request(
	struct i2c_engine *engine,
	struct i2c_request_transaction_data *req)
{
	struct i2c_sw_engine *sw_engine = FROM_I2C_ENGINE(engine);

	struct ddc *ddc = engine->base.ddc;
	uint16_t clock_delay_div_4 = sw_engine->clock_delay >> 2;

	/* send sync (start / repeated start) */

	bool result = start_sync(engine->base.ctx, ddc, clock_delay_div_4);

	/* process payload */

	if (result) {
		switch (req->action) {
		case I2CAUX_TRANSACTION_ACTION_I2C_WRITE:
		case I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT:
			result = i2c_write(engine->base.ctx, ddc, clock_delay_div_4,
				req->address, req->length, req->data);
		break;
		case I2CAUX_TRANSACTION_ACTION_I2C_READ:
		case I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT:
			result = i2c_read(engine->base.ctx, ddc, clock_delay_div_4,
				req->address, req->length, req->data);
		break;
		default:
			result = false;
		break;
		}
	}

	/* send stop if not 'mot' or operation failed */

	if (!result ||
		(req->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
		(req->action == I2CAUX_TRANSACTION_ACTION_I2C_READ))
		if (!stop_sync(engine->base.ctx, ddc, clock_delay_div_4))
			result = false;

	req->status = result ?
		I2C_CHANNEL_OPERATION_SUCCEEDED :
		I2C_CHANNEL_OPERATION_FAILED;
}
static void start_pm(void)
{
	uint16_t from, to;

	state = SCAN_STATE_PM;
	from = band_range[pm_index][0];
	to = band_range[pm_index][1];

	if (from == 0 && to == 0) {
		LOGP(DSUM, LOGL_INFO, "Measurement done\n");
		pm_gps_valid = g.enable && g.valid;
		if (pm_gps_valid)
			geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z,
				g.longitude, g.latitude);
		log_pm();
		start_sync();
		return;
	}
	LOGP(DSUM, LOGL_INFO, "Measure from %d to %d\n", from, to);
	l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
	l1ctl_tx_pm_req_range(ms, from, to);
}
Exemple #9
0
static int8_t tpsn_net_module_handler(void *state, Message *msg)
{
    app_state_t *s = (app_state_t *) state;
    MsgParam *p = (MsgParam*)(msg->data);

    /**
     * Switch to the correct message handler
     */
    switch (msg->type)
    {
    case MSG_INIT:
    {

        msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t));
        DEBUG("TPSN NET: Started\n");

        s->pid = msg->did;
        s->level = -1;
        s->parent_id = 0;
        s->last_refresh = 0;
        s->sync_state = INIT;
        s->current_seq_no = 0;

        // try to join the sync tree
        msg_adv_level->level = s->level;
        sys_post_net(s->pid, MSG_ADV_LEVEL, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, BCAST_ADDRESS);
        sys_timer_start(ADV_TIMER_ID, 5*1024, TIMER_REPEAT);
        return SOS_OK;
    }

    case MSG_GET_GLOBAL_TIME:
    {
        DEBUG("TPSN_NET: state: %d\n", s->sync_state);
        msg_global_time_t* time_msg = (msg_global_time_t*)msg->data;
        msg_global_time_t* time_reply_msg = (msg_global_time_t*)sys_malloc(sizeof(msg_global_time_t));

        if(s->sync_state == SYNCED || s->sync_state == SYNCING) {
            // we are synced, and thus had at least one time sync exchange
            // if we are level 1, then just return our time
            if(s->level == 1) {
                time_reply_msg->time = time_msg->time;
                time_reply_msg->refreshed = 0;
            } else {
                uint32_t delta_refresh = 0;
                uint32_t cur_time = sys_time32();
                // check for overflow
                if(cur_time < s->last_refresh) {
                    cur_time += 0x7F000000;
                }
                delta_refresh = cur_time - s->last_refresh;
                // only try to refresh if we are not already syncing.
                if (s->sync_state == SYNCED && delta_refresh > REFRESH_INTERVAL) {
                    DEBUG("TPSN_NET: Refresh needed refresh: %d\n", delta_refresh);
                    s->sync_state = SYNCING;

                    start_sync();
                }
                // even though we might be syncing, reply with the current estimate.
                time_reply_msg->time = time_msg->time + s->clock_drift;
                time_reply_msg->refreshed = delta_refresh;
            }
        } else {
            time_reply_msg->time = NOT_SYNCED;
            time_reply_msg->refreshed = NOT_SYNCED;
        }
        DEBUG("TPSN_NET: converted time for module %d, drift %d, refreshed %d, global time %d, sync state %d\n", msg->sid, s->clock_drift, time_reply_msg->refreshed, time_reply_msg->time, s->sync_state);
        sys_post(msg->sid, MSG_GLOBAL_TIME_REPLY, sizeof(msg_global_time_t), time_reply_msg, SOS_MSG_RELEASE);

        return SOS_OK;
    }

    case MSG_TIMESTAMP:
    {
        DEBUG("TPSN_NET: state: %d\n", s->sync_state);
        LED_DBG(LED_RED_TOGGLE);
        tpsn_req_t *tpsn_req_ptr = (tpsn_req_t *)msg->data;
        switch(tpsn_req_ptr->type) {
        case TPSN_REQUEST:
        {
            DEBUG("TPSN_NET: Received TPSN_REQUEST (seq_no=%d) from node %d\n", tpsn_req_ptr->seq_no, msg->saddr);
            DEBUG("TPSN_NET: Transmitting TPSN_REPLY to node %d at time %d\n", msg->saddr, sys_time32());
            tpsn_reply_t *tpsn_reply_ptr = (tpsn_reply_t *)sys_malloc(sizeof(tpsn_reply_t));
            memcpy(tpsn_reply_ptr->previous_time, tpsn_req_ptr->time, sizeof(tpsn_req_ptr->time));
            tpsn_reply_ptr->type = TPSN_REPLY;
            tpsn_reply_ptr->seq_no = tpsn_req_ptr->seq_no;
            if(msg->saddr == UART_ADDRESS) {
                sys_post_uart(s->pid, MSG_TIMESTAMP, sizeof(tpsn_reply_t), tpsn_reply_ptr, SOS_MSG_RELEASE, msg->saddr);
            } else {
                sys_post_net(s->pid, MSG_TIMESTAMP, sizeof(tpsn_reply_t), tpsn_reply_ptr, SOS_MSG_RELEASE, msg->saddr);
            }
            break;
        }
        case TPSN_REPLY:
        {
            if(s->sync_state == SYNCING || s->sync_state == INIT_SYNCING) {
                //LED_DBG(LED_YELLOW_TOGGLE);

                DEBUG("TPSN: Received TPSN_REPLY from node %d\n", msg->saddr);
                tpsn_reply_t *tpsn_reply_ptr = (tpsn_reply_t *)msg->data;
                if (tpsn_reply_ptr->seq_no == s->current_seq_no) {
                    sys_timer_stop(SYNC_TIMER_ID);
                    s->current_seq_no++;

                    //T1=tpsn_reply_ptr->previous_time[0]
                    //T2=tpsn_reply_ptr->previous_time[1]
                    //T3=tpsn_reply_ptr->time[0]
                    //T4=tpsn_reply_ptr->time[1]
                    //CLOCK_DRIFT = ((T2 - T1) - (T4 - T3))/2
                    //PROPAGATION_DELAY=((T2 - T1) + (T4 - T3))/2

                    //Take care of overflow in the node that sent the TPSN request (T1 > T4)
                    if(tpsn_reply_ptr->previous_time[0] > tpsn_reply_ptr->time[1])
                        tpsn_reply_ptr->time[1] += INT_MAX_GTIME;

                    //Take care of overflow in the node that sent the TPSN reply (T2 > T3)
                    if(tpsn_reply_ptr->previous_time[1] > tpsn_reply_ptr->time[0])
                        tpsn_reply_ptr->time[0] += INT_MAX_GTIME;

                    s->clock_drift = ( ((int32_t)tpsn_reply_ptr->previous_time[1] - (int32_t)tpsn_reply_ptr->previous_time[0]) -
                                       ((int32_t)tpsn_reply_ptr->time[1] - (int32_t)tpsn_reply_ptr->time[0]) )/2;
                    s->last_refresh = sys_time32();
                    s->sync_state = SYNCED;
                    DEBUG("TPSN: The clock offset for node %d is %d\n", msg->saddr, s->clock_drift);
                }
            }
            break;
        }
        default:
        {
            DEBUG("Received unknown packet\n");
            break;
        }
        }
    }

    case MSG_TIMER_TIMEOUT:
    {
        DEBUG("TPSN_NET: state: %d\n", s->sync_state);
        switch(p->byte)
        {
        case ADV_TIMER_ID:
        {
            if( s->sync_state == INIT) {
                // try to join the sync tree
                DEBUG("TPSN_NET: Trying to join sync tree. Sending out ADV\n");
                msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t));
                msg_adv_level->level = s->level;
                sys_post_net(s->pid, MSG_ADV_LEVEL, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, BCAST_ADDRESS);
            }
            break;
        }
        case SYNC_TIMER_ID:
        {
            if(s->sync_state == SYNCING || s->sync_state == INIT_SYNCING)
            {
                // didn't receive the timestamp in time. Try to resend
                DEBUG("TPSN_NET: SYNC_TIMER fired. Trying to sync again.\n");
                start_sync();
            }
            break;
        }
        default:
            break;
        }
        return SOS_OK;
    }

    case MSG_ADV_LEVEL:
    {
        // FIXME: only allow level 1 to reply for now!
        if ( s->sync_state == SYNCED && s->level < 2) {
            msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t));
            msg_adv_level->level = s->level;
            sys_post_net(s->pid, MSG_ADV_REPLY, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, msg->saddr);

        }
        return SOS_OK;
    }

    case MSG_ADV_REPLY:
    {
        DEBUG("TPSN_NET: state: %d\n", s->sync_state);
        msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)msg->data;
        if ( (s->sync_state == INIT) || msg_adv_level->level < s->level) {
            DEBUG("TPSN_NET: received new level %d from %d\n", msg_adv_level->level, msg->saddr);
            sys_timer_stop(ADV_TIMER_ID);
            s->level = msg_adv_level->level+1;
            s->parent_id = msg->saddr;

            if(s->level == 1) {
                // special case for root.
                msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t));
                msg_adv_level->level = s->level;
                sys_post_net(s->pid, MSG_ADV_REPLY, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, msg->saddr);

                s->sync_state = SYNCED;
            } else {
                s->sync_state = INIT_SYNCING;
                start_sync();
            }
        }
        return SOS_OK;
    }

    case MSG_FINAL:
    {
        return SOS_OK;
    }


    default:
        return -EINVAL;
    }

    /**
     * Return SOS_OK for those handlers that have successfully been handled.
     */
    return SOS_OK;
}
static void sig_func(int sig_nr) {
    (void)sig_nr;
    start_sync();
    flag = 1;
}