Example #1
0
void* recv_th(void* pParam) {
  //while(1) {
    Udp udp;
    udp.initAddr(54321, "192.168.10.179");
    udp.send("hoge");
    //std::string data = udp.recieve();

    //std::cout << data << std::endl;
    
    //picojson::value val;
    //picojson::parse(val, data);
    //picojson::object obj = val.get<picojson::object>();
    //posX = obj["posx"].get<double>();
    //posY = obj["posy"].get<double>();
    
    //int sock;
    //sockaddr_in addr;

  //sock = socket(AF_INET, SOCK_DGRAM, 0);

  //addr.sin_family = AF_INET;
  //addr.sin_port = htons(54321);
  //addr.sin_addr.s_addr = inet_addr("192.168.10.179");

  //int res = sendto(sock, val.serialize().c_str(), val.serialize().size(), 0, (sockaddr*)&addr, sizeof(addr));
  //std::cout << val.serialize().c_str() << " : " << val.serialize().size() << " : " << res << std::endl;
  //close(sock);
  //}
}
Example #2
0
void* send_th(void* pParam) {
  while(1) {
    picojson::object obj;
    obj.insert(std::make_pair("posx", picojson::value(posX)));
    obj.insert(std::make_pair("posy", picojson::value(posY)));
    picojson::value val(obj);

    Udp udp;
    udp.initAddr((u_short)54321, "192.168.101.92");
    udp.send(val.serialize());
  }
}
Example #3
0
    Udp * Udp::New(/* [in] */ Loop &loop)
    {
        Udp *self = new Udp();
        if(! self) {
            return NULL;
        }

        if(! self->Open(loop)) {
            return self;
        }

        delete self;

        return NULL;
    }
Example #4
0
int Handle(const GwcHead &reqHead, const TReq &reqBody, GwcHead &rspHead, TResp &rspBody) {
	string ip = p.GetStr("ip", "127.0.0.1");
	uint16_t port = (uint16_t)p.GetU32("port", SERVER_PORT);
	uint32_t timeout = p.GetU32("timeout", 10000);
	string proto = p.GetStr("proto", "");

	char req[0x10000];
	uint32_t reqLen = sizeof(req);

	mtroe(code(reqHead, reqBody, req, reqLen), "");

	char rsp[0x10000];
	uint32_t rspLen = sizeof(rsp);

	in_addr addr = {inet_addr(ip.c_str())};
	printf(	"--------------------------------------------------------------------------------\n"
			"request host: address=%s:%u, timeout=%u\n"
			"request head: msgType=%u, version=%u, bodyLen=%lu\n"
			"request body: \n%s"
			"--------------------------------------------------------------------------------\n"
			, inet_ntoa(addr), port, timeout
			, reqHead.msgType, reqHead.version, reqLen - sizeof(reqHead)
			, reqBody.DebugString().c_str());

	if ("udp" == proto) {
		Udp udp;
		udp.SetTimeout(timeout);
		mtroe(udp.SendRecv(ip, port, req, reqLen, rsp, rspLen), "Udp::SendRecv failed, %s", udp.GetLastErr());
	} else {
		Tcp tcp;
		tcp.SetSendTimeout(timeout);
		tcp.SetTimeout(timeout);
		mtroe(tcp.SendRecv(ip, port, req, reqLen, rsp, rspLen), "Tcp::SendRecv failed, %s", tcp.GetLastErr());
	}

	mtroe(decode(rsp, rspLen, rspHead, rspBody), "");

	printf("--------------------------------------------------------------------------------\n"
			"response head: msgType=%u, version=%u, bodyLen=%lu\n"
			"response body: \n%s"
			"--------------------------------------------------------------------------------\n"
			, rspHead.msgType, rspHead.version, rspLen - sizeof(rspHead)
			, rspBody.DebugString().c_str());


	return 0;
}
packetDecoder::packetDecoder()
{
    //ctor

    // add protocols to RegProtocol
    RegProtocol.clear();
    Ethernet *ethIns = new Ethernet();
    RegProtocol[ethIns->getProtoId()] = ethIns;

    IP *ipIns = new IP();
    RegProtocol[ipIns->getProtoId()] = ipIns;

    Udp *udpIns = new Udp();
    RegProtocol[udpIns->getProtoId()] = udpIns;

    TCP *tcpIns = new TCP();
    RegProtocol[tcpIns->getProtoId()] = tcpIns;
}
Example #6
0
    void Udp::OnSend(/* [in] */ uv_udp_send_t *req,
                     /* [in] */ int status)
    {
        Udp *self = (Udp *) req->data;
        Buffer *sendBuffer = self->m_pSendBuffer;
        self->m_pSendBuffer = NULL;

        if(self->m_pSendHandler) {
            SendHandler *sendHandler = self->m_pSendHandler;
            self->m_pSendHandler = NULL;

            sendHandler->OnSend(self, status);
        }

        sendBuffer->Unlock();
        sendBuffer->Unref();

        if(status) {
            self->Close();
        }

        self->Unref();
    }
Example #7
0
    void Udp::OnRecv(/* [in] */ uv_udp_t *peer,
                     /* [in] */ ssize_t nread, 
                     /* [in] */ const uv_buf_t *buf,
                     /* [in] */ const sockaddr *addr,
                     /* [in] */ unsigned flags)
    {
        if(! nread) {
            Buffer::Free(buf->base);
            return;
        }

        Udp *self = (Udp *) peer->data;
        Buffer *buffer = NULL;
        if(0 < nread) {
            buffer = new Buffer(buf, nread);
        }

        Address address;
        if(addr) {
            address.Set(addr);
        }

        self->m_pRecvHandler->OnRecv(self,
                                     buffer,
                                     address,
                                     flags,
                                     0 > nread ? nread : 0);

        if(buffer) {
            buffer->Unref();
        }

        if(0 > nread) {
            self->Close();
        }
    }
Example #8
0
/** main */
int
main(int argc, char *argv[])
{
	Args args = parseOption(argc, argv);
	// 正常終了時戻り値
	int result = 0;
	boost::scoped_ptr<Recordable> tuner(NULL);
	timeval tv_start;
#ifdef UDP
	Udp udp;
#endif /* defined(UDP) */
#ifdef HTTP
	int dest = 1; // stdout
	int connected_socket = 0;
	int listening_socket = 0;
#endif /* defined(HTTP) */
	
	// 引数確認
	if (!args.forever && args.recsec <= 0) {
		std::cerr << "recsec must be (recsec > 0)." << std::endl;
		exit(1);
	}
	
	// 録画時間の基準開始時間
	time_t time_start = time(NULL);
	
	// ログ出力先設定
	std::ostream& log = args.stdout ? std::cerr : std::cout;

#ifdef HTTP
	if( !args.http_mode ){
		// 出力先ファイルオープン
		if(!args.stdout) {
			dest = open(args.destfile, (O_RDWR | O_CREAT | O_TRUNC), 0666);
			if (0 > dest) {
				std::cerr << "can't open file '" << args.destfile << "' to write." << std::endl;
				exit(1);
			}
		}
	}else{
		struct sockaddr_in	sin;
		int					sock_optval = 1;
		int					ret;

		fprintf(stderr, "run as a daemon..\n");
		if(daemon(1,1)){
			perror("failed to start");
			exit(1);
		}

		listening_socket = socket(AF_INET, SOCK_STREAM, 0);
		if ( listening_socket == -1 ){
			perror("socket");
			exit(1);
		}

		if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, &sock_optval, sizeof(sock_optval)) == -1 ){
			perror("setsockopt");
			exit(1);
		}

		sin.sin_family = AF_INET;
		sin.sin_port = htons(args.http_port);
		sin.sin_addr.s_addr = htonl(INADDR_ANY);

		if ( bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0 ){
			perror("bind");
			exit(1);
		}

		ret = listen(listening_socket, SOMAXCONN);
		if ( ret == -1 ){
			perror("listen");
			exit(1);
		}
		fprintf(stderr,"listening at port %d\n", args.http_port);
	}

	while(1){
		if ( args.http_mode ) {
			struct sockaddr_in	peer_sin;
			int					read_size;
			unsigned int		len;
			char				buffer[256];
			char				s0[256],s1[256],s2[256];
			char				delim[] = "/";
			char				*channel;
			char				*sidflg;

			len = sizeof(peer_sin);
			connected_socket = accept(listening_socket, (struct sockaddr *)&peer_sin, &len);
			if ( connected_socket == -1 ) {
				perror("accept");
				exit(1);
			}

			int error;
			char hbuf[NI_MAXHOST], nhbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
			error = getnameinfo((struct sockaddr *)&peer_sin, sizeof(peer_sin), hbuf, sizeof(hbuf), NULL, 0, 0);
			if (error) {
				fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(error));
				exit(1);
			}
			error = getnameinfo((struct sockaddr *)&peer_sin, sizeof(peer_sin), nhbuf, sizeof(nhbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
			if (error) {
				fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(error));
				exit(1);
			}
			fprintf(stderr,"connect from: %s [%s] port %s\n", hbuf, nhbuf, sbuf);

			read_size = read_line(connected_socket, buffer);
			fprintf(stderr, "request command is %s\n", buffer);
			// ex:GET /C8/333 HTTP/1.1
			sscanf(buffer, "%s%s%s", s0, s1, s2);
			channel = strtok(s1, delim);
			if (channel != NULL) {
				fprintf(stderr, "Channel: %s\n", channel);
				parseChannel(&args, channel);
				sidflg = strtok(NULL, delim);
				if (sidflg != NULL) {
					fprintf(stderr, "SID: %s\n", sidflg);
#ifdef TSSL
					args.splitter = true;
					args.sid_list = sidflg;
				} else {
					args.splitter = false;
					args.sid_list = NULL;
#endif /* defined(TSSL) */
				}
			}
			char header[] =  "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nCache-Control: no-cache\r\n\r\n";
			write(connected_socket, header, strlen(header));
			//set write target to http
			dest = connected_socket;
		}
#endif /* defined(HTTP) */

#ifdef B25
	// B25初期化
	B25Decoder b25dec;
	if (args.b25) {
		try {
			b25dec.setRound(args.round);
			b25dec.setStrip(args.strip);
			b25dec.setEmmProcess(args.emm);
			b25dec.open();
			log << "B25Decoder initialized." << std::endl;
		} catch (b25_error& e) {
			std::cerr << e.what() << std::endl;
			
#ifdef HTTP
			if (!args.http_mode) {
#endif /* defined(HTTP) */
			// エラー時b25を行わず処理続行。終了ステータス1
			std::cerr << "disable b25 decoding." << std::endl;
			args.b25 = false;
			result = 1;
#ifdef HTTP
			}
#endif /* defined(HTTP) */
		}
	}
#endif /* defined(B25) */

#ifdef UDP
	// UDP初期化
	if( ! args.ip.empty() ){
		try{
			udp.setLog(&log);
			udp.init( args.ip, args.port );
		}
		catch( const char* e ){
			log << e << std::endl;
			log << "disable UDP." << std::endl;
		}
	}
#endif /* defined(UDP) */

#ifdef TSSL
	/* initialize splitter */
	splitbuf_t splitbuf;
	splitbuf.size = 0;
	splitter *splitter = NULL;
	int split_select_finish = TSS_ERROR;
	int code;
	if(args.splitter) {
		splitter = split_startup(args.sid_list);
		if(splitter->sid_list == NULL) {
			fprintf(stderr, "Cannot start TS splitter\n");
			return 1;
		}
	}
#endif /* defined(TSSL) */

	// Tuner取得
	tuner.reset(createRecordable(args.type));
#ifdef HDUS
	if( args.type == TUNER_HDUS ) log << "Tuner type is HDUS." << std::endl;
	else if( args.type == TUNER_HDP ) log << "Tuner type is HDP." << std::endl;
#endif /* defined(HDUS) */
	// ログ出力先設定
	tuner->setLog(&log);
	// ロックファイル設定
	if (args.lockfile != NULL) {
		tuner->setDetectLockFile(args.lockfile);
	}
	
	// Tuner初期化
	int retryCount = ERROR_RETRY_MAX;
	while (0 < retryCount) {
		try {
			// チューナopen
			bool r = tuner->open(args.lnb);
			if (!r) {
				std::cerr << "can't open tuner." << std::endl;
				exit(1);
			}
			
			// チャンネル設定
			tuner->setChannel(args.band, args.channel);
			
			// 開始時SignalLevel出力
			float lev_before = 0.0;
			int lev_retry_count = SIGNALLEVEL_RETRY_MAX;
			while (lev_before < SIGNALLEVEL_RETRY_THRESHOLD && 0 < lev_retry_count) {
				lev_before = tuner->getSignalLevel();
				log << "Signal level: " << lev_before << std::endl;
				
				lev_retry_count--;
				usleep(SIGNALLEVEL_RETRY_INTERVAL * 1000);
			}
		} catch (usb_error& e) {
			// リトライ処理
			retryCount--;
			std::cerr << e.what();
			if (retryCount <= 0) {
				std::cerr << " abort." << std::endl;
				exit(1);
			}
			std::cerr << " retry." << std::endl;
			
			tuner->close();
			usleep(ERROR_RETRY_INTERVAL * 1000);
			continue;
		}
		break;
	}
	
#ifndef HTTP
	// 出力先ファイルオープン
	FILE *dest = stdout;
	if (!args.stdout) {
		dest = fopen(args.destfile, "w");
		if (NULL == dest) {
			std::cerr << "can't open file '" << args.destfile << "' to write." << std::endl;
			exit(1);
		}
	}
#endif /* !defined(HTTP) */
	
	// 出力開始/時間計測
	log << "Output ts file." << std::endl;
	if (gettimeofday(&tv_start, NULL) < 0) {
		std::cerr << "gettimeofday failed." << std::endl;
		exit(1);
	}
	
	// SIGINT/SIGTERMキャッチ
	struct sigaction sa;
	memset(&sa, 0, sizeof(struct sigaction));
	sa.sa_handler = sighandler;
	sa.sa_flags = SA_RESTART;
	struct sigaction saDefault;
	memset(&saDefault, 0, sizeof(struct sigaction));
	saDefault.sa_handler = SIG_DFL;
	sigaction(SIGINT,  &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGPIPE, &sa, NULL);
	
	uint8_t		*buf = NULL;
	int			rlen;
	
	// 受信スレッド起動
	tuner->startStream();
	// データ読み出し
	uint32_t urb_error_cnt = 0;
	while (!caughtSignal && (args.forever || time(NULL) <= time_start + args.recsec)) {
		try {
			rlen = tuner->getStream((const uint8_t **)&buf, 200);
			if (0 == rlen) {
				continue;
			}
			
#ifdef B25
			// B25を経由させる。
			if (args.b25) {
				static int f_b25_sync = 0;
				try {
					uint8_t *b25buf;
					b25dec.put(buf, rlen);
					rlen = b25dec.get((const uint8_t **)&b25buf);
					if (0 == rlen) {
						continue;
					}
					f_b25_sync = 1;
					buf = b25buf;
				} catch (b25_error& e) {
					if( f_b25_sync == 0 && args.sync ){
						log << "Wait for B25 sync" << std::endl;
						continue;
					}
					log << "B25 Error: " << e.what() << std::endl;
					log << "Continue recording without B25." << std::endl;
#ifdef HTTP
					if (!args.http_mode) {
#endif /* defined(HTTP) */
					// b25停止、戻り値エラー
					args.b25 = false;
					result = 1;
#ifdef HTTP
					}
#endif /* defined(HTTP) */
				}
			}
#endif /* defined(B25) */

#ifdef TSSL
			if (args.splitter) {
				splitbuf.size = 0;
				while (rlen) {
					/* 分離対象PIDの抽出 */
					if (split_select_finish != TSS_SUCCESS) {
						split_select_finish = split_select(splitter, buf, rlen);
						if (split_select_finish == TSS_NULL) {
							/* mallocエラー発生 */
							log << "split_select malloc failed" << std::endl;
							args.splitter = false;
							result = 1;
							goto fin;
						} else if (split_select_finish != TSS_SUCCESS) {
							// 分離対象PIDが完全に抽出できるまで出力しない
							// 1秒程度余裕を見るといいかも
							time_t cur_time;
							time(&cur_time);
							if (cur_time - time_start > 4) {
								args.splitter = false;
								result = 1;
								goto fin;
							}
							break;
						}
					}
					/* 分離対象以外をふるい落とす */
					code = split_ts(splitter, buf, rlen, &splitbuf);
					if (code != TSS_SUCCESS) {
						log << "split_ts failed" << std::endl;
						break;
					}
					break;
				}

				rlen = splitbuf.size;
				buf = splitbuf.buffer;
			fin:
				;
			}
#endif /* defined(TSSL) */

#ifdef UDP
			// UDP 配信
			udp.send(buf, rlen);
#endif /* defined(UDP) */

#ifdef HTTP
			while(rlen > 0) {
				ssize_t wc;
				int ws = rlen < SIZE_CHUNK ? rlen : SIZE_CHUNK;
				while(ws > 0) {
					wc = write(dest, buf, ws);
					if(wc < 0) {
						log << "write failed." << std::endl;
						rlen = 0;
						buf = NULL;
						break;
					}
					ws -= wc;
					rlen -= wc;
					buf += wc;
				}
			}
#else
			fwrite(buf, 1, rlen, dest);
#endif /* defined(HTTP) */

		} catch (usb_error& e) {
			if (urb_error_cnt <= URB_ERROR_MAX) {
				log << e.what() << std::endl;
				if (urb_error_cnt == URB_ERROR_MAX) {
					log << "Too many URB error." << std::endl;
				}
				urb_error_cnt++;
			}
		}
	}
	if (caughtSignal) {
#ifdef HTTP
		if( args.http_mode )
			caughtSignal = false;
		else
#endif /* defined(HTTP) */
		log << "interrupted." << std::endl;
	}
	// 受信スレッド停止
	tuner->stopStream();
	
	// シグナルハンドラを戻す。
	sigaction(SIGINT,  &saDefault, NULL);
	sigaction(SIGTERM, &saDefault, NULL);
	sigaction(SIGPIPE, &saDefault, NULL);

	rlen = 0;
	buf = NULL;

#ifdef B25
	// B25デコーダ内のデータを出力する。
	if (args.b25) {
		try {
			b25dec.flush();
			rlen = b25dec.get((const uint8_t **)&buf);
		} catch (b25_error& e) {
			log << "B25 Error: " << e.what() << std::endl;
			result = 1;
		}
	}
#endif /* defined(B25) */
#ifdef TSSL
	if (args.splitter) {
		splitbuf.size = 0;
		while (rlen) {
			/* 分離対象PIDの抽出 */
			if (split_select_finish != TSS_SUCCESS) {
				split_select_finish = split_select(splitter, buf, rlen);
				if (split_select_finish == TSS_NULL) {
					/* mallocエラー発生 */
					log << "split_select malloc failed" << std::endl;
					args.splitter = false;
					result = 1;
					break;
				} else if (split_select_finish != TSS_SUCCESS) {
					// 分離対象PIDが完全に抽出できるまで出力しない
					// 1秒程度余裕を見るといいかも
					time_t cur_time;
					time(&cur_time);
					if (cur_time - time_start > 4) {
						args.splitter = false;
						result = 1;
					}
					break;
				}
			}
			/* 分離対象以外をふるい落とす */
			code = split_ts(splitter, buf, rlen, &splitbuf);
			if (code != TSS_SUCCESS) {
				log << "split_ts failed" << std::endl;
				break;
			}
			break;
		}
		rlen = splitbuf.size;
		buf = splitbuf.buffer;
		split_shutdown(splitter);
	}
#endif /* defined(TSSL) */
#ifdef HTTP
		while(rlen > 0) {
			ssize_t wc;
			int ws = rlen < SIZE_CHUNK ? rlen : SIZE_CHUNK;
			while(ws > 0) {
				wc = write(dest, buf, ws);
				if(wc < 0) {
					log << "write failed." << std::endl;
					rlen = 0;
					buf = NULL;
					break;
				}
				ws -= wc;
				rlen -= wc;
				buf += wc;
			}
		}
		if( args.http_mode ){
			/* close http socket */
			close(dest);
			fprintf(stderr,"connection closed. still listening at port %d\n", args.http_port);
		}else
			break;
	}
#else
	if (0 < rlen) {
		fwrite(buf, 1, rlen, dest);
	}
#endif /* defined(HTTP) */

	// 時間計測
	timeval tv_end;
	if (gettimeofday(&tv_end, NULL) < 0) {
		err(1, "gettimeofday failed.");
	}
	
	// 出力先ファイルクローズ
#ifdef HTTP
	if (!args.stdout) {
		close(dest);
	}
#else
	fflush(dest);
	if (!args.stdout) {
		fclose(dest);
	}
#endif /* defined(HTTP) */
	log << "done." << std::endl;
	
#ifdef UDP
	// UDP クローズ
	udp.shutdown();
#endif /* defined(UDP) */
	
	// 録画時間出力
	timeval rec_time;
	timersub(&tv_end, &tv_start, &rec_time);
	log << "Rec time: " << rec_time.tv_sec << "." << std::setfill('0') << std::setw(6) << rec_time.tv_usec << " sec." << std::endl;
	
	// 終了時SignalLevel出力
	try {
		float lev_after = tuner->getSignalLevel();
		log << "Signal level: " << lev_after << std::endl;
	} catch (usb_error& e) {
		log << e.what() << " ignored." << std::endl;
	}
	
	return result;
}