コード例 #1
0
ファイル: trnc.c プロジェクト: schwehr/mb-system
/// @fn int s_trnc_state_machine(iow_socket_t *s, app_cfg_t *cfg)
/// @brief state machine implementation
/// @param[in] s iow_socket_t reference
/// @param[in] cfg app_cfg reference
/// @return none
static int s_trnc_state_machine(iow_socket_t *s, app_cfg_t *cfg)
{
    int retval=-1;
    int scycles=cfg->cycles;
    int trn_tx_count=0;
    int trn_rx_count=0;
    int trn_tx_bytes=0;
    int trn_rx_bytes=0;
    int trn_msg_count=0;
    int trn_msg_bytes=0;
    const char *reqstr="REQ\0";
    
    if (NULL!=s) {
        
        // initialize variables
        trn_message_t message;
        trn_message_t *pmessage = &message;
        mbtrn_header_t *pheader = &pmessage->data.header;
        mbtrn_sounding_t *psounding = &pmessage->data.sounding;
        
        memset(pmessage,0,sizeof(message));
        int hbeat_counter=0;
        int64_t test=0;
        byte *pread=NULL;
        uint32_t readlen=0;
        
        trnc_state_t state=ST_INIT;
        trnc_action_t action=AT_NOP;
        
        // state machine entry point
        while (state != ST_DONE && !g_interrupt) {
            
            // check states, assign actions
            switch (state) {
                case ST_INIT:
                    memset(&message,0,MBTRN_MAX_MSG_BYTES);
                    action = AT_CONNECT;
                    break;
                case ST_CONNECTED:
                    action=AT_WR_REQ;
                    break;
                case ST_REQ_PENDING:
                case ST_SUBSCRIBED:
                    memset(&message,0,MBTRN_MAX_MSG_BYTES);
                    action=AT_RD_MSG;
                    break;
                case ST_HBEAT_EXPIRED:
                    action=AT_WR_REQ;
                    break;
                    
                default:
                    break;
            }// switch
            
            // action: connect
            if (action == AT_CONNECT) {
                MMDEBUG(ID_APP,"connecting [%s:%d]\n",cfg->host,cfg->port);
                if( (test=iow_connect(s))==0 ) {
                    MMDEBUG(ID_APP,"connect OK\n");
                    state=ST_CONNECTED;
                }else{
                    MERROR("connect failed [%"PRId64"]\n",test);
                }
            }
            
            // action: write request
            if (action == AT_WR_REQ) {
                
                test=iow_sendto(s,NULL,(byte *)reqstr,4,0);
                
                MMDEBUG(ID_APP,"sendto REQ ret[%"PRId64"] [%d/%s]\n",test,errno,strerror(errno));
                
                if( test>0 ){
                    trn_tx_count++;
                    trn_tx_bytes+=test;
                    state=ST_REQ_PENDING;
                }else{
                    MMDEBUG(ID_APP,"sendto failed ret[%"PRId64"] [%d/%s]\n",test,errno,strerror(errno));
                }
            }
            
            // action: read response
            if (action == AT_RD_MSG) {
                pread = (byte *)&message;
                readlen = MBTRN_MAX_MSG_BYTES;
                // request message
                if ((test = iow_recvfrom(s, NULL, pread, readlen))>0) {
                    
                    trn_rx_bytes+=test;
                    trn_rx_count++;
                    
                    // check message type
                    if (pheader->type==MBTRN_MSGTYPE_ACK) {
                        MMDEBUG(ID_APP,"received ACK ret[%"PRId64"] [%08X]\n",test,pheader->type);
                        hbeat_counter=0;
                        state=ST_SUBSCRIBED;
                    }else if (pheader->type==MBTRN_MSGTYPE_MB1) {
                        MMDEBUG(ID_APP,"received MSG ret[%"PRId64"] type[%08X] size[%d] ping[%06d]\n",test,pheader->type,pheader->size,psounding->ping_number);
                        trn_msg_count++;
                        trn_msg_bytes+=test;
                        
                        action=AT_SHOW_MSG;
                        
                        if (state==ST_REQ_PENDING) {
                            state=ST_REQ_PENDING;
                        }else{
                            state=ST_SUBSCRIBED;
                        }
                        hbeat_counter++;
                        MMDEBUG(ID_APP,"hbeat[%d/%d]\n",hbeat_counter,cfg->hbeat);
                        if ( (hbeat_counter!=0) && (hbeat_counter%cfg->hbeat==0)) {
                            state=ST_HBEAT_EXPIRED;
                        }
                    }else{
                        // response not recognized
                        MMDEBUG(ID_APP,"invalid message [%08X]\n",pheader->type);
                    }
                }else{
                    // read returned error
                    //  MMDEBUG(ID_APP,"invalid message [%d]\n",test);
                    switch (errno) {
                        case EWOULDBLOCK:
                            // nothing to read
                            //   MMDEBUG(ID_APP,"err - [%d/%s]\n",errno, strerror(errno));
                            break;
                        case ENOTCONN:
                        case ECONNREFUSED:
                            // host disconnected
                            MMDEBUG(ID_APP,"err - server not connected [%d/%s]\n",errno, strerror(errno));
                            iow_socket_destroy(&s);
                            s = iow_socket_new(cfg->host, cfg->port, ST_UDP);
                            iow_set_blocking(s,(cfg->blocking==0?false:true));
                            sleep(5);
                            state=ST_INIT;
                            retval=-1;
                            break;
                        default:
                            MMDEBUG(ID_APP,"err ? [%d/%s]\n",errno, strerror(errno));
                            break;
                    }//switch
                }
            }
            
            // action: show message
            if (action == AT_SHOW_MSG) {
                MMDEBUG(ID_APP,"\nts[%.3f] ping[%06d] lat[%.4lf] lon[%.4lf]\nsd[%7.2lf] hdg[%6.2lf] nb[%03"PRIu32"]\n",
                        psounding->ts,
                        psounding->ping_number,
                        psounding->lat,
                        psounding->lon,
                        psounding->depth,
                        psounding->hdg,
                        (uint32_t)psounding->nbeams);
                uint32_t j=0;
                struct mbtrn_beam_data *bd=psounding->beams;
                for (j=0; j<psounding->nbeams; j++,bd++){
                    MMDEBUG(ID_APP,"n[%03"PRIu32"] atrk/X[% 10.3lf] ctrk/Y[% 10.3lf] dpth/Z[% 10.3lf]\n",
                            (uint32_t)bd->beam_num,
                            bd->rhox,
                            bd->rhoy,
                            bd->rhoz);
                }
            }
            
            // action: quit state machine
            if (action == AT_QUIT) {
                break;
            }
            
            // check cycles and signals
            scycles--;
            if(scycles==0){
                MTRACE();
                retval=0;
                state=ST_DONE;
            }
            
            if(g_interrupt){
                MTRACE();
                retval=-1;
                state=ST_DONE;
            }
            
        }// while !ST_DONE
    }//else invalid arg
    
    MMINFO(ID_APP,"tx count/bytes[%d/%d]\n",trn_tx_count,trn_tx_bytes);
    MMINFO(ID_APP,"rx count/bytes[%d/%d]\n",trn_rx_count,trn_rx_bytes);
    MMINFO(ID_APP,"trn count/bytes[%d/%d]\n",trn_msg_count,trn_msg_bytes);
    
    return retval;
}
コード例 #2
0
bool
TMXLoader::Private::processMap(XMLElement &m)
{
	if ((XML_SUCCESS != m.QueryIntAttribute("width", &map_size.width))
	 || (XML_SUCCESS != m.QueryIntAttribute("height", &map_size.height))
	 || (XML_SUCCESS != m.QueryIntAttribute("tilewidth", &tile_size.width))
	 || (XML_SUCCESS != m.QueryIntAttribute("tileheight", &tile_size.height))) {
		MMWARNING("Map element is missing one or more required attributes.");
		return(false);
	}

	/* default scale */
	scale.set(1.f, 1.f);

	/* process properties */
	XMLElement *l_properties = m.FirstChildElement(TMXPROPERTIES_NODE);
	XMLElement *l_property = l_properties ? l_properties->FirstChildElement(TMXPROPERTIES_PROPERTY_NODE) : 0;
	if (l_property)
	do {
		const char *l_pname = l_property->Attribute("name");
		if (!l_pname)
			continue;

		/* scale property */
		if (0 == MMSTRCASECMP(l_pname, "scale")) {
			const char *l_value = l_property->Attribute("value");
			if (!l_value) {
				MMWARNING("Skipping incomplete scale property.");
				continue;
			}

			if (0 == MMSTRCASECMP(l_value, "screen")) {
				const Math::Size2f &l_vsize = Graphics::Viewport::Size();
				const Math::Size2i &l_wsize = Graphics::Viewport::WindowSize();

				/*
				 * calculate pixels per viewport coordinate ratio
				 * scale ratio = vSize (vcoord)) / wSize (pixels)
				 */
				scale = l_vsize / l_wsize.cast<float>();

				continue;
			}
			else if (2 == sscanf(l_value, "%fx%f", &scale.width, &scale.height))
				continue;
			else if (1 == sscanf(l_value, "%f", &scale.width)) {
				scale.height = scale.width;
				continue;
			}

			MMERROR("Invalid scale value encountered.");
			continue;
		}

		/*
		 * Parse scene background color
		 */
		else if (0 == MMSTRCASECMP(l_pname, "bgcolor")) {
			const char *l_value = l_property->Attribute("value");
			if (!l_value) {
				MMWARNING("Skipping incomplete background color property.");
				continue;
			}

			/*
			 * Valid formats: #RRGGBB, RRGGBB.
			 */
			uint16_t l_pxl[3];
			if ((sscanf(l_value, "#%2hx%2hx%2hx",
			        &l_pxl[0], &l_pxl[1], &l_pxl[2]) != 3) &&
			    (sscanf(l_value,  "%2hx%2hx%2hx",
			        &l_pxl[0], &l_pxl[1], &l_pxl[2]) != 3)) {
				MMWARNING("Skipping invalid background color value.");
				continue;
			}

			/* set background color */
			Game::SceneBase &l_scene_base =
			    static_cast<Game::SceneBase &>(scene);
			l_scene_base.setBackground(PixelToColor(l_pxl));
			continue;
		}

	} while ((l_property = l_property->NextSiblingElement(TMXPROPERTIES_PROPERTY_NODE)));

	MMINFO("Map scale size (" << scale.width << "x" << scale.height << ")");

	/* calculate half-relative map size (used to offset coordinates) */
	hrmap_size.width = scale.width
	    * static_cast<float>(map_size.width  * tile_size.width);
	hrmap_size.height = scale.height
	    * static_cast<float>(map_size.height * tile_size.height);

	return(true);
}