Beispiel #1
0
void PacketFunctions::WriteNT(const MString& data)
{
	unsigned int index=0;
	while ((Position<NETMAXBUFFERSIZE)&&(index<data.length()))
		Data[Position++] = (unsigned char)(data.c_str()[index++]);
	Data[Position++] = 0;
}
int BlsChild::processCommand(MString &line)
{
    if (line.empty()) return E_SUCCESS;

    if (line.endWith("\n")) {
        line.erase(line.size()-1, 1);
    }
    log_trace("BlsMasterChannel get line %s", line.c_str());

    MStringList temp = line.split(Internal_CMD_Delimer);
    MString key = temp.at(0);
    MString value = temp.at(1);

    if (key == Internal_CMD_PID) {
        m_pid = value.toInt();
        gs_childs[m_pid] = this;
    } else if (key == Internal_CMD_InternalPort) {
        m_internalPort = value.toInt();
    } else if (key == Internal_CMD_WhoHasBackSource) {
        MRtmpUrl rtmpUrl(value);
        MString url = rtmpUrl.url();

        int port = 0;
        if (gs_sources.contains(url)) {
            port = gs_sources[url]->internalPort();
        }

        if (sendLine(Internal_CMD_WhoHasBackSourceRes, MString::number(port)) != E_SUCCESS) {
            return -1;
        }

        log_trace("--%s:%d", url.c_str(), port);

        if (port == 0) {
            gs_sources[url] = this;
        }
    } else if (key == Internal_CMD_IHasBackSourced) {
        log_warn("%s insert into backsource queue", value.c_str());
        gs_sources[value] = this;
    } else if (key == Internal_CMD_RemoveHasBackSourceRes) {
        log_warn("%s removed from backsource queue", value.c_str());
        gs_sources.erase(value);
    }

    return E_SUCCESS;
}
Beispiel #3
0
bool MDir::exists(const MString &dirName)
{
    // only access returns 0, we consider the dir is existed.
    if (access(dirName.c_str(), F_OK) == 0) {
        return true;
    }

    return false;
}
Beispiel #4
0
//取当前连接的IP地址和端口号
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ClientComm::GetCurrentLinkMsg( char * IPAddr,unsigned short *Port )
{
	if( ( IPAddr == NULL  )||( Port == NULL ) )
	{
		return;
	}

	MString ip = Global_Option.GetSrvIP( m_sCurrentServerPos );
	strcpy( IPAddr,ip.c_str() );

	*Port = Global_Option.GetPort( m_sCurrentServerPos );
}
Beispiel #5
0
bool ezSockets::Connect(const MString& host, unsigned short port)
{
	if(!Check())
		return false;

#if defined(_XBOX)
	if(!isdigit(host[0])) // don't do a DNS lookup for an IP address
	{
		XNDNS *pxndns = NULL;
		XNetDnsLookup(host.c_str(), NULL, &pxndns);
		while (pxndns->iStatus == WSAEINPROGRESS)
		{
			// Do something else while lookup is in progress
		}

		if (pxndns->iStatus == 0)
			memcpy(&addr.sin_addr, &pxndns->aina[0], sizeof(struct in_addr));
		else
			return false;

		XNetDnsRelease(pxndns);
	}
	else
		addr.sin_addr.s_addr = inet_addr(host.c_str());
#else
	struct hostent* phe;
	phe = gethostbyname(host.c_str());
	if (phe == NULL)
		return false;
	memcpy(&addr.sin_addr, phe->h_addr, sizeof(struct in_addr));
#endif
	addr.sin_family = AF_INET;
	addr.sin_port   = htons(port);

	if(::connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
		return false;

	state = skCONNECTED;
	return true;
}
Beispiel #6
0
bool MDir::createDir(const MString &dirName)
{
    // process multi "//" to one "/"
    MString dn = dirName;
    dn.push_back('/');
    dn.replace("//", "/");

    int index = dn.startWith("/") ? 1 : 0;
    for (unsigned int i = index; i < dn.size(); ++i) {
        char &c = dn[i];

        if (c == '/') {
            c = '\0';
            int ret = access(dn.c_str(), F_OK);
            if (ret == 0) {
                c = '/';
                continue;
            }

            ret = mkdir(dn.c_str(), 0744);
            if (ret == 0) {
                c = '/';
                continue;
            }

//            if (errno == ENOENT) {
//                ret = mkdir(dn.c_str(), 0744);
//                if (ret == 0) {
//                    continue;
//                }
//            }

            merrno = errno;
            return false;
        }
    }

    return true;
}
Beispiel #7
0
BOOL Option::BinarySearch(const char *szKey)
{
	int left;
	int right;
	int mid;
	MString str;

	/**
	 *	没有配置needlist,表示不进行查找控制
	 *	虽然和needlist的含义有点背,主要为兼容考虑的.
	 */
	if(m_nNeedCnt == 0)
		return TRUE;

	str.Empty();
	str = szKey;
	if(m_IsCase)
	{
		str.Lower();
	}

	left = 0;
	right = m_nNeedCnt - 1;

	while(left <= right)
	{
		mid = (left + right) / 2;
		if(strcmp(m_stNeedArray[mid].szValue, str.c_str()) == 0)
			return TRUE;
		else if(strcmp(m_stNeedArray[mid].szValue, str.c_str()) < 0)
			left = mid + 1;
		else
			right= mid - 1;
	}

	return FALSE;
}
Beispiel #8
0
//..............................................................................................................................
int  MDll::LoadDll(MString strFileName, void *hModule)
{
	#ifndef LINUXCODE

		if ( (m_hDll = ::LoadLibrary(strFileName.c_str())) == NULL )
		{
			return(MErrorCode::GetSysErr());
		}

		return(1);

	#else

		if ( (m_lpDll = dlopen(strFileName.c_str(),RTLD_LAZY)) == NULL )
		{
			printf("dlopen: %d , %s\n", errno, dlerror()); fflush(stdout);
			return(MErrorCode::GetSysErr());
		}

		typedef int	fnDllMain(void  * , unsigned long, void *);
		fnDllMain	*pfnDllMain;
		pfnDllMain = (fnDllMain *)dlsym(m_lpDll, "DllMain");
		if(!pfnDllMain)
		{
			printf("WARNING:(%s) undefined symbol: DllMain\n", strFileName.c_str());fflush(stdout);
			return ERR_MDLL_LOSTDLLMAIN;
		}

		MergeDllSelfPath(strFileName.c_str(), hModule);

		pfnDllMain(this, 0, NULL);

		return(1);

	#endif
}
Beispiel #9
0
MString Detranslit( const MString & inputText )
{
    MString sEndChat;

    const char* chatStr = inputText.c_str();
    for ( unsigned int i = 0; i < inputText.length(); i++ )
    {
        if ( (unsigned char )( chatStr[i] ) >= (unsigned char )( 0xE0 ) )
            i+=2;
        else if ( (unsigned char )( chatStr[i] ) >= (unsigned char )( 0xC0 ) )
            i+=1;
        else
            sEndChat += chatStr[i];
    }
    return sEndChat;
}
int MRtmpConnection::run()
{
    int ret = E_SUCCESS;

    if ((ret = m_protocol->handshakeWithClient()) != E_SUCCESS) {
        return ret;
    }

    while (!RequestStop) {
        MRtmpMessage *msg = NULL;
        int res = m_protocol->recv_message(&msg);
        if (res == E_SOCKET_CLOSE_NORMALLY) {
            break;
        }

        if (res != E_SUCCESS) {
            log_error("MRtmpConnection recv_message error.");
            break;
        }

        mMSleep(10);
    }

    if (m_role == Role_Connection_Publish) {
        MString url = m_protocol->getRtmpCtx()->url();
        g_cchannel->sendLine(Internal_CMD_RemoveHasBackSourceRes, url);
        BlsBackSource::instance()->remove(url);

        log_trace("remove url from master(url=%s)", url.c_str());
    }

    m_socket->close();
    deleteLater();

    log_trace("MRtmpConnection exit normally.");

    return E_SUCCESS;
}
Beispiel #11
0
void Option::BubbleSort()
{
	/**
	 *	strcmp function
	 *	str1 > str2 @return >0
	 *	str1 < str2 @return <0
	 */
	int		i, j;
	char	szTemp[32];
	MString	str;

	if(m_IsCase)
	{
		for(i = 0; i < m_nNeedCnt; i++)
		{
			str.Empty();
			str = m_stNeedArray[i].szValue;
			str.Lower();
			strcpy(m_stNeedArray[i].szValue, str.c_str());
		}
	}

	for(i = 0; i < m_nNeedCnt - 1; i++)
	{
		for(j = i + 1; j < m_nNeedCnt; j++)
		{
			if(strcmp(m_stNeedArray[i].szValue, m_stNeedArray[j].szValue) > 0)
			{
				memset(szTemp, 0, sizeof(szTemp));
				strncpy(szTemp, m_stNeedArray[i].szValue, sizeof(szTemp));
				strncpy(m_stNeedArray[i].szValue, m_stNeedArray[j].szValue, sizeof(m_stNeedArray[i].szValue));
				strncpy(m_stNeedArray[j].szValue, szTemp, sizeof(m_stNeedArray[j].szValue));
			}
		}
	}
}
Beispiel #12
0
//Yuck, this algorithm is kind of slow...
bool ezSockets::ReadLine( MString & str )
{
	if ( mode != skGeneral )
		return false;

	str = "";
	ReceiveGeneralData();

	ezSocketsPacket * tmp = pDataInHead;

	bool bFound = false;
	int i = 0;

	while ( tmp )
	{
		for ( i = tmp->Position; i < (int)(tmp->PositionTAG); i++ )
			if ( tmp->Data[i] == '\n' )
			{
				bFound = true;
				break;
			}
		if ( !bFound )
			tmp = tmp->Next;
		else
			break;
	}

	if ( !bFound && !bBlocking )
		return false;

	if ( bFound )
		while ( pDataInHead != tmp )
		{
			str.append( pDataInHead->Data, pDataInHead->Size-pDataInHead->Position );
			pDataInHead = pDataInHead->Next;
		}

	if ( pDataInHead )
		if ( i != pDataInHead->Position )
		{
			str.append( pDataInHead->Data + pDataInHead->Position, i - pDataInHead->Position );
			pDataInHead->Position = i + 1;
		}

	//Keep waiting for more data
	if ( !bFound && bBlocking )
	{
		if ( pDataInHead )
			pDataInHead->Position = pDataInHead->PositionTAG;

		char tmp = '\0';
		while ( tmp != '\n' )
		{
			if ( ReadLeftover( &tmp, 1 ) != 1 )
				return false;
			if ( tmp != '\n' )
				str.append( &tmp, 1 );
		}
	}

	if ( str.length() > 0 )
		if ( str.c_str()[str.length()-1] == '\r' )
			str.resize ( str.length() - 1 );

	return true;
}
Beispiel #13
0
void * __stdcall ClientComm::ClientCommThreadFun( void * pIn )
{
	ClientComm				*	classptr;
	fd_set							readfdset;
	int								maxselectno;
	char							tempbuf[8192];
	register int					errorcode;
	MCounter						counter;
	MCounter						TimeoutCount;
	bool							recvdataflag = false;

	classptr = ( ClientComm * )pIn;

	counter.SetCurTickCount();
	while ( classptr->m_ClientCommThread.GetThreadStopFlag( ) == false )
	{
		try
		{
			//检查连接状况
			if( !classptr->GetLinkFlg() )
			{
				if( !classptr->CreatLink( ) )
				{
					classptr->m_sCurrentServerPos++;

					continue;
				}

				MThread::Sleep(5000);

				if( classptr->OnConnectSrvSuc( ) < 0 )
				{
					continue;
				}

				classptr->m_bConnectFlg = true;	//	GUOGUO 20110518
				
				TimeoutCount.SetCurTickCount();
			}
			
			if( counter.GetDuration() >= (Global_Option.GetHeartIntervalTime() * 1000) )
			{
				counter.SetCurTickCount();
				classptr->OnTime();
			}
			maxselectno = (int)classptr->m_clientsocket;

			FD_ZERO(&readfdset);
			FD_SET(classptr->m_clientsocket,&readfdset);
			if( MSocket::Select( classptr->m_clientsocket,&readfdset,NULL,NULL,1000 ) != 1 )
			{
				//if( TimeoutCount.GetDuration() > 60000 )
				if( TimeoutCount.GetDuration() > (Global_Option.GetTimeOut() * 1000))
				{
					MString	strErr;
					strErr.Format("长达%d秒没有数据到达,关闭当前连接", Global_Option.GetTimeOut());
					classptr->OnConnectClose( strErr.c_str() );
					continue;
				}
				continue;
			}

			if( FD_ISSET( classptr->m_clientsocket,&readfdset ) )
			{
				TimeoutCount.SetCurTickCount();
				if ( ( errorcode = recv( classptr->m_clientsocket,tempbuf,8192,0 ) ) <= 0 )
				{
					//对方已经关闭连接
					classptr->CloseLink( false );
					classptr->OnConnectClose( ( MString("连接被断开,")+MErrorCode::GetErrString( MErrorCode::GetSysErr() )).c_str() );
					continue;
				}

				if ( classptr->OnRecvData( tempbuf,errorcode ) < 0 )
				{
					classptr->CloseLink( false );
					classptr->OnConnectClose( "错误的数据处理, 主动断开连接" );
				}

			}
		}
		catch( ... )
		{
			slib_WriteError( Global_UnitNo, 0, "[通讯单元]:通讯接收线程发生未知异常。");
		}
	}

	return(0);
}
Beispiel #14
0
/* Once we get here, we should be * safe to do whatever we want;
* heavyweights like malloc and MString are OK. (Don't crash!) */
static void child_process()
{
	//cout<<"in process"<<endl;
    /* 1. Read the CrashData. */
//    if( !child_read(3, &crash, sizeof(CrashData)) )
	///WOOT FOR HACKS

	//return;

	const char *home = getenv( "HOME" );
	MString sCrashInfoPath = "/tmp";
	if( home )
		sCrashInfoPath = home;
	sCrashInfoPath += "/crashinfo.txt";

	FILE *CrashDump = fopen( sCrashInfoPath, "w+" );
	if(CrashDump == NULL)
	{
		fprintf( stderr, "Couldn't open " + sCrashInfoPath + ": %s\n", strerror(errno) );
		exit(1);
	}

    fprintf(CrashDump, "%s crash report", PRODUCT_NAME_VER );
#if defined(HAVE_VERSION_INFO)
    fprintf(CrashDump, " (build %u)", version_num);
#endif
    fprintf(CrashDump, "\n");
    fprintf(CrashDump, "--------------------------------------\n");
    fprintf(CrashDump, "\n");

    MString reason;
    switch( crash.type )
    {
    case CrashData::SIGNAL:
    {
	MString Signal = SignalName( crash.signal );

#if !defined(DARWIN)
	reason = ssprintf( "%s - %s", Signal.c_str(), SignalCodeName(crash.signal, crash.si.si_code) );
#else
	reason = Signal;
#endif
	switch( crash.signal )
	{
	case SIGILL:
	case SIGFPE:
	case SIGSEGV:
	case SIGBUS:
	    if( crash.si.si_code == SI_USER )
		    reason += ssprintf( " from pid %li", (long) crash.si.si_addr );
	    else
		    reason += ssprintf( " at 0x%0*lx", int(sizeof(void*)*2), (unsigned long) crash.si.si_addr );
	}
	break;
    }
    case CrashData::FORCE_CRASH:
	crash.reason[ sizeof(crash.reason)-1] = 0;
	reason = crash.reason;
	break;
    }

    fprintf( CrashDump, "Crash reason: %s\n", reason.c_str() );
    //fprintf( CrashDump, "Crashed thread: %s\n\n", CrashedThread.c_str() );

//    fprintf(CrashDump, "Checkpoints:\n");
//    for (unsigned i=0; i<Checkpoints.size(); ++i)
//        fprintf(CrashDump, Checkpoints[i]);
//    fprintf(CrashDump, "\n");

    for( int i = 0; i < CrashData::MAX_BACKTRACE_THREADS; ++i )
    {
	    if( !crash.BacktracePointers[i][0] )
		    break;
	    fprintf( CrashDump, "Thread: %s\n", crash.m_ThreadName[i] );
	    output_stack_trace( CrashDump, crash.BacktracePointers[i] );
	    fprintf(CrashDump, "\n");
    }

    fprintf(CrashDump, "Static log:\n");
	//+++ add static log here
    fprintf(CrashDump, "-- End of report\n");
    fclose(CrashDump);

#if defined(DARWIN)
    InformUserOfCrash( sCrashInfoPath );
    
    /* Forcibly kill our parent. */
    kill( getppid(), SIGKILL );
#else
    /* stdout may have been inadvertently closed by the crash in the parent;
     * write to /dev/tty instead. */
    FILE *tty = fopen( "/dev/tty", "w" );
    if( tty == NULL )
        tty = stderr;

    fprintf(tty,
            "\n"
            PRODUCT_NAME " has crashed.  Debug information has been output to\n"
            "\n"
            "    " + sCrashInfoPath + "\n"
            "\n"
            "Please report a bug at:\n"
            "\n"
            "    http://sourceforge.net/tracker/?func=add&group_id=121611&atid=690872"
            "\n"
            );
#endif
}
Beispiel #15
0
//..............................................................................................................................
int  MThread::StartThread(MString strName, tagMThreadFunction fpFunction,void * lpParam,bool bCheckAlive)
{
	s_bStopAllThread = false;
	
	StopThread();

	m_bStopCurThread = false;
	//add by liuqy 20100817 for 启动线程时,需要复位系统参数
	rv_Reset();

	#ifndef LINUXCODE

		register int				errorcode;
		
		m_hRecordData = (HANDLE)_beginthreadex(	0,
												0,
												(unsigned int (__stdcall *)(void *))fpFunction,
												lpParam,
												0,
												(unsigned int *)&errorcode	);
		if ( m_hRecordData == NULL )
		{
			return(MErrorCode::GetSysErr());
		}
		//modify by liuqy 20100817 for 保存线程ID号
		//SetSpObejctName((strName+"_pid:"+MString(errorcode)).c_str());
		m_ulThreadID = errorcode;
		SetSpObejctName(strName.c_str());
		//end mdofiy by liuqy
		if ( bCheckAlive == true )
		{
			inner_setactive();
		}
		
		return(1);

	#else

		/*
		 *	LINUX pthread_create创建的线程的堆栈是10MB
		 *	我们的程序通常用不到那么大,所以调整为2MB
		 *	这样可以减少逻辑地址
		 */
		pthread_attr_t thread_attr;
		size_t stack_size;

		if(pthread_attr_init(&thread_attr) != 0)
		{
			return(MErrorCode::GetSysErr());
		}

		//设置线程栈空间为2M.
		stack_size = 2048*1024;
		if(pthread_attr_setstacksize(&thread_attr, stack_size) != 0)
		{
			return(MErrorCode::GetSysErr());
		}

		if ( pthread_create(&m_hRecordData,&thread_attr,fpFunction,lpParam) != 0 )
		{
			return(MErrorCode::GetSysErr());
		}
		//add by liuqy 20100817 for 保存线程ID号
		m_ulThreadID = m_hRecordData;
		
		SetSpObejctName(strName.c_str());

		if ( bCheckAlive == true )
		{
			inner_setactive();
		}
		
		return(1);

	#endif
}
Beispiel #16
0
void ezSockets::SendData(const MString& outData)
{
	if ( mode == skGeneral )
		pWriteData( outData.c_str(), outData.length() );
}
Beispiel #17
0
void ezSocketsPacket::WriteNT( const MString& Info )
{
	Grow( Position + Info.length() + 1 );
	memcpy( &Data[Position], Info.c_str(), Info.length()+1 );
	Position += Info.length()+1;
}
int MRtmpConnection::onCommand(MRtmpMessage *msg, const MString &name, double transactionID, MAMF0Any *arg1
                               , MAMF0Any *arg2, MAMF0Any *arg3, MAMF0Any *arg4)
{
    // TODO refer check.
    // TODO set app msg to protocol
    int ret = E_SUCCESS;

    if (name == "connect") {
        if (!arg1->isAmf0Object()) return E_AMF_TYPE_ERROR;

        MAMF0Object *obj = dynamic_cast<MAMF0Object *>(arg1);
        if ((ret = parseUrl(obj)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->setAckSize(2500000)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->setPeerBandwidth(2500000)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->onConnect(transactionID)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->onBWDone()) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "releaseStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverConnection);

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, new MAMF0Undefined)) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "FCPublish") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverConnection);

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, new MAMF0Undefined)) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "createStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverConnection);

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID)
                                       , new MAMF0Null, new MAMF0Number(1))) != E_SUCCESS)
        {
            return ret;
        }
        m_protocol->getRtmpCtx()->streamID = 1;
    } else if (name == "publish") {
        MString cmdName = "FCPublish";
        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverStream);

        MRtmpNetStatusEvent *obj = new MRtmpNetStatusEvent(NetStream_Publish_Start);
        obj->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Publish_Start));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj)) != E_SUCCESS) {
            return ret;
        }

        MRtmpNetStatusEvent *obj1 = new MRtmpNetStatusEvent(NetStream_Publish_Start, STATUS_LEVEL_STATUS);
        obj1->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Publish_Start));
        obj1->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendNetStatusEvent(transactionID, obj1)) != E_SUCCESS) {
            return ret;
        }

        MAMF0ShortString *str = dynamic_cast<MAMF0ShortString *>(arg2);
        if (!str) {
            return E_AMF_TYPE_ERROR;
        }

        MRtmpContext *ctx = m_protocol->getRtmpCtx();
        ctx->setStreamName(str->var);

        MString url = ctx->rtmpUrl->url();
        m_source = MRtmpSource::findSource(url);
        m_role = Role_Connection_Publish;

        log_trace("start publish %s", url.c_str());

        g_cchannel->sendLine(Internal_CMD_IHasBackSourced, url);
        BlsBackSource::instance()->setHasBackSource(url);

    } else if (name == "FCUnpublish") {
        MString cmdName = "onFCUnpublish";
        MAMF0Object *obj = new MAMF0Object;
        obj->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Unpublish_Success));
        obj->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Unpublish_Success));

        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverConnection);

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj)) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "closeStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverConnection);

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID)
                                       , new MAMF0Null, new MAMF0Undefined)) != E_SUCCESS)
        {
            return ret;
        }

        cmdName = RTMP_AMF0_COMMAND_ON_STATUS;
        MAMF0Object *obj1 = new MAMF0Object;
        obj1->setValue(STATUS_LEVEL, new MAMF0ShortString(STATUS_LEVEL_STATUS));
        obj1->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Unpublish_Success));
        obj1->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Unpublish_Success));
        obj1->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj1)) != E_SUCCESS) {
            return ret;
        }
        m_protocol->getRtmpCtx()->streamID = 0;
    } else if (name == "deleteStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverConnection);

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID)
                                       , new MAMF0Null, new MAMF0Null)) != E_SUCCESS)
        {
            return ret;
        }
    } else if (name == "play") {
        if ((ret = m_protocol->setChunkSize(40960)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->setUCM(UCM_StreamBegin, m_protocol->getRtmpCtx()->streamID)) != E_SUCCESS) {
            return ret;
        }

        MRtmpMessageHeader header(RTMP_MSG_AMF0CommandMessage, RTMP_CID_OverConnection2);
        MString cmdName = RTMP_AMF0_COMMAND_ON_STATUS;

        MRtmpNetStatusEvent *obj = new MRtmpNetStatusEvent(NetStream_Play_Reset, STATUS_LEVEL_STATUS);
        obj->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Play_Reset));
        obj->setValue(STATUS_DETAILS, new MAMF0ShortString(NetStream_Play_Reset));
        obj->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj)) != E_SUCCESS) {
            return ret;
        }

        MAMF0Object *obj1 = new MAMF0Object;
        obj1->setValue(STATUS_LEVEL, new MAMF0ShortString(STATUS_LEVEL_STATUS));
        obj1->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Play_Start));
        obj1->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Play_Start));
        obj1->setValue(STATUS_DETAILS, new MAMF0ShortString(NetStream_Play_Start));
        obj1->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj1)) != E_SUCCESS) {
            return ret;
        }

        header.type = RTMP_MSG_AMF0DataMessage;
        cmdName = RTMP_AMF0_DATA_SAMPLE_ACCESS;
        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Boolean(false), new MAMF0Boolean(false))) != E_SUCCESS) {
            return ret;
        }

        MAMF0ShortString *str = dynamic_cast<MAMF0ShortString *>(arg2);
        if (!str) {
            return E_AMF_TYPE_ERROR;
        }

        MRtmpContext *ctx = m_protocol->getRtmpCtx();
        ctx->setStreamName(str->var);
        MString url = ctx->rtmpUrl->url();

        MString vhost = ctx->rtmpUrl->vhost();
        MString mode = BlsConf::instance()->getMode(vhost);
        MString fullUrl = ctx->rtmpUrl->fullUrl();

        bool hasBackSource = BlsBackSource::instance()->hasBackSource(fullUrl);
        if (!hasBackSource) {
            // TODO if fails ?
            MString res;
            g_cchannel->sendLineAndWaitResponse(Internal_CMD_WhoHasBackSource, url, res);
            int port = getValue(res).toInt();

            if (mode == Mode_Remote) {
                if (port == 0) {
                    // back source to local server
                    BlsBackSource::instance()->add(ctx->rtmpUrl->vhost(), ctx->rtmpUrl->port(), ctx->rtmpUrl->app(), ctx->rtmpUrl->fullUrl());
                    log_trace("begin back source to %s:%d pid=%d", ctx->rtmpUrl->vhost().c_str(), ctx->rtmpUrl->port(), getpid());
                } else if (port > 0) {
                    // back source to origin server
                    BlsBackSource::instance()->add("127.0.0.1", port, ctx->rtmpUrl->app(), ctx->rtmpUrl->fullUrl());
                    log_trace("begin back source to %s:%d pid=%d", "127.0.0.1", port, getpid());
                }
            } else if (mode == Mode_Local) {
                BlsBackSource::instance()->add("127.0.0.1", port, ctx->rtmpUrl->app(), ctx->rtmpUrl->fullUrl());      // back source to origin server
            }
        }

        log_trace("start play : %s", fullUrl.c_str());

        m_source = MRtmpSource::findSource(url);
        m_role = Role_Connection_Play;
        playService();

    } else if (name == "_checkbw") {
        return ret;
    }

    else {
        log_error("MRtmpConnection onCommand : no method \"%s\"", name.c_str());
        return E_INVOKE_NO_METHOD;
    }

    return ret;
}
int MRtmpConnection::onCommand(MRtmpMessage *msg, const MString &name, double transactionID, MAMF0Any *arg1
                               , MAMF0Any *arg2, MAMF0Any *arg3, MAMF0Any *arg4)
{
    // TODO refer check.
    // TODO set app msg to protocol
    int ret = E_SUCCESS;

    if (name == "connect") {
        if (!arg1->isAmf0Object()) return E_AMF_TYPE_ERROR;

        MAMF0Object *obj = dynamic_cast<MAMF0Object *>(arg1);
        if ((ret = parseUrl(obj)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->setAckSize(2500000)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->setPeerBandwidth(2500000)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->onConnect(transactionID)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->onBWDone()) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "releaseStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverConnection;
        header.type = RTMP_MSG_AMF0CommandMessage;

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, new MAMF0Undefined)) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "FCPublish") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverConnection;
        header.type = RTMP_MSG_AMF0CommandMessage;

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, new MAMF0Undefined)) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "createStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverConnection;
        header.type = RTMP_MSG_AMF0CommandMessage;

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID)
                                       , new MAMF0Null, new MAMF0Number(1))) != E_SUCCESS)
        {
            return ret;
        }
        m_protocol->getRtmpCtx()->streamID = 1;
    } else if (name == "publish") {
        MString cmdName = "FCPublish";
        MAMF0Object *obj = new MAMF0Object;
        obj->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Publish_Start));
        obj->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Publish_Start));

        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverStream;
        header.type = RTMP_MSG_AMF0CommandMessage;

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj)) != E_SUCCESS) {
            return ret;
        }

        cmdName = RTMP_AMF0_COMMAND_ON_STATUS;
        MAMF0Object *obj1 = new MAMF0Object;
        obj1->setValue(STATUS_LEVEL, new MAMF0ShortString(STATUS_LEVEL_STATUS));
        obj1->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Publish_Start));
        obj1->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Publish_Start));
        obj1->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj1)) != E_SUCCESS) {
            return ret;
        }

        MAMF0ShortString *str = dynamic_cast<MAMF0ShortString *>(arg2);
        if (!str) {
            return E_AMF_TYPE_ERROR;
        }
        MRtmpContext *ctx = m_protocol->getRtmpCtx();
        ctx->setStreamName(str->var);

        MString url = ctx->rtmpUrl->url();
        m_source = new MRtmpSource(url, this);
        log_trace("start publish %s", url.c_str());

    } else if (name == "FCUnpublish") {
        MString cmdName = "onFCUnpublish";
        MAMF0Object *obj = new MAMF0Object;
        obj->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Unpublish_Success));
        obj->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Unpublish_Success));

        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverConnection;
        header.type = RTMP_MSG_AMF0CommandMessage;

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj)) != E_SUCCESS) {
            return ret;
        }
    } else if (name == "closeStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverConnection;
        header.type = RTMP_MSG_AMF0CommandMessage;

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID)
                                       , new MAMF0Null, new MAMF0Undefined)) != E_SUCCESS)
        {
            return ret;
        }

        cmdName = RTMP_AMF0_COMMAND_ON_STATUS;
        MAMF0Object *obj1 = new MAMF0Object;
        obj1->setValue(STATUS_LEVEL, new MAMF0ShortString(STATUS_LEVEL_STATUS));
        obj1->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Unpublish_Success));
        obj1->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Unpublish_Success));
        obj1->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj1)) != E_SUCCESS) {
            return ret;
        }
        m_protocol->getRtmpCtx()->streamID = 0;
    } else if (name == "deleteStream") {
        MString cmdName = RTMP_AMF0_COMMAND_RESULT;
        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverConnection;
        header.type = RTMP_MSG_AMF0CommandMessage;

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID)
                                       , new MAMF0Null, new MAMF0Null)) != E_SUCCESS)
        {
            return ret;
        }
    } else if (name == "play") {
        if ((ret = m_protocol->setChunkSize(4096)) != E_SUCCESS) {
            return ret;
        }

        if ((ret = m_protocol->setUCM(UCM_StreamBegin, m_protocol->getRtmpCtx()->streamID)) != E_SUCCESS) {
            return ret;
        }

        MRtmpMessageHeader header;
        header.perfer_cid = RTMP_CID_OverConnection2;
        header.type = RTMP_MSG_AMF0CommandMessage;

        MString cmdName = RTMP_AMF0_COMMAND_ON_STATUS;

        MAMF0Object *obj = new MAMF0Object;
        obj->setValue(STATUS_LEVEL, new MAMF0ShortString(STATUS_LEVEL_STATUS));
        obj->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Play_Reset));
        obj->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Play_Reset));
        obj->setValue(STATUS_DETAILS, new MAMF0ShortString(NetStream_Play_Reset));
        obj->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj)) != E_SUCCESS) {
            return ret;
        }

        MAMF0Object *obj1 = new MAMF0Object;
        obj1->setValue(STATUS_LEVEL, new MAMF0ShortString(STATUS_LEVEL_STATUS));
        obj1->setValue(STATUS_CODE, new MAMF0ShortString(NetStream_Play_Start));
        obj1->setValue(STATUS_DESC, new MAMF0ShortString(NetStream_Play_Start));
        obj1->setValue(STATUS_DETAILS, new MAMF0ShortString(NetStream_Play_Start));
        obj1->setValue(STATUS_CLIENT_ID, new MAMF0ShortString("ASAICiss"));

        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Number(transactionID), new MAMF0Null, obj1)) != E_SUCCESS) {
            return ret;
        }

        header.type = RTMP_MSG_AMF0DataMessage;
        cmdName = RTMP_AMF0_DATA_SAMPLE_ACCESS;
        if ((ret = m_protocol->sendAny(header, new MAMF0ShortString(cmdName), new MAMF0Boolean(false), new MAMF0Boolean(false))) != E_SUCCESS) {
            return ret;
        }

        MAMF0ShortString *str = dynamic_cast<MAMF0ShortString *>(arg2);
        if (!str) {
            return E_AMF_TYPE_ERROR;
        }

        MRtmpContext *ctx = m_protocol->getRtmpCtx();
        ctx->setStreamName(str->var);
        MString url = ctx->rtmpUrl->url();
        while (true) {
            MRtmpSource *source = MRtmpSource::findSource(url);
            if (!source) {
                mSleep(1);
                continue;
            }

            m_source = source;
            break;
        }

        log_trace("start play : %s", url.c_str());
        playService();
    } else if (name == "_checkbw") {
        return ret;
    }

    else {
        log_error("MRtmpConnection onCommand : no method \"%s\"", name.c_str());
        return E_INVOKE_NO_METHOD;
    }

    return ret;
}
Beispiel #20
0
void ezSockets::WriteLine( const MString & str )
{
	SendData( str.c_str(), str.length() );
	SendData( "\r\n", 1 );
}