⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.cpp

📁 C++ modem驱动代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		CHECK_LEN(8)		setDateTime(tmp,(char*)pdata,8);		params.addParam("datetime",tmp);		break;	    case CompDateTime:           // 5.4.10		if (param == CompDateTime && len != 8 && len != 10) {		    Debug(this,DebugNote,			"Invalid len=%u (expected 8 or 10) for %s parameter [%p]",len,pname,this);		    continue;		}		setDateTime(tmp,(char*)pdata,len);		params.addParam("service_datetime",tmp);		break;	    case CalledId:               // 5.4.3		SET_PARAM_FROM_DATA("called")		break;	    case CallType:               // 5.4.12		CHECK_LEN(1)		SET_PARAM_FROM_DICT("calltype",s_dict_callType)		break;	    case CallerType:             // 5.4.16		CHECK_LEN(1)		SET_PARAM_FROM_DICT("originator_type",s_dict_callerType)		break;	    case VisualIndicator:        // 5.4.7		CHECK_LEN(1)		if (*pdata == 0 || *pdata == 255)		    tmp = String::boolText(*pdata);		else		    tmp = (int)(*pdata);		params.addParam("visualindicator",tmp);		break;	    case MessageId:              // 5.4.8		CHECK_LEN(3)		SET_PARAM_FROM_DICT("message_status",s_dict_mwiStatus)		params.addParam("message_ref",String(net2short(pdata + 1)));		DDebug(this,DebugInfo,		    "Decoded %s parameter (status=%s ref=%d) [%p]",		    pname,tmp.c_str(),net2short(pdata + 1),this);		continue;	    case LastMsgCLI:             // 5.4.9		SET_PARAM_FROM_DATA("message_caller")		break;	    case CompCallerId:           // 5.4.11		SET_PARAM_FROM_DATA("caller_networkprovided")		break;	    case FirstCalledId:          // 5.4.13		SET_PARAM_FROM_DATA("ffwd_first")		break;	    case MWICount:               // 5.4.14		CHECK_LEN(1)		tmp = (int)(*pdata);		params.addParam("message_count",tmp);		break;	    case FwdCallType:            // 5.4.15		CHECK_LEN(1)		SET_PARAM_FROM_DICT("ffwd_reason",s_dict_ffwdReason)		break;	    case RedirNumber:            // 5.4.17		SET_PARAM_FROM_DATA("ffwd_last")		break;	    case Charge:                 // 5.4.18	        Debug(this,DebugStub,"Skipping %s parameter [%p]",pname,this);		continue;	    case AdditionalCharge:       // 5.4.19	        Debug(this,DebugStub,"Skipping %s parameter [%p]",pname,this);		continue;	    case Duration:               // 5.4.20		CHECK_LEN(6)		setDateTime(tmp,(char*)pdata,6);		params.addParam("duration",tmp);		break;	    case NetworkID:              // 5.4.21		SET_PARAM_FROM_DATA("netid")		break;	    case CarrierId:              // 5.4.22		SET_PARAM_FROM_DATA("carrierid")		break;	    case SelectFunction:         // 5.4.23	        Debug(this,DebugStub,"Skipping %s parameter [%p]",pname,this);		continue;	    case Display:                // 5.4.24	        Debug(this,DebugStub,"Skipping %s parameter [%p]",pname,this);		continue;	    case ServiceInfo:            // 5.4.25		CHECK_LEN(1)		if (*pdata > 1)		    tmp = (int)(*pdata);		else		    tmp = *pdata ? "active" : "not-active";		params.addParam("service_info",tmp);		break;	    case Extension:              // 5.4.26	        Debug(this,DebugStub,"Skipping %s parameter [%p]",pname,this);		continue;	}#undef SET_PARAM_FROM_DATA#undef SET_PARAM_FROM_DICT#undef CHECK_LEN	DDebug(this,DebugAll,"Decoded %s=%s [%p]",pname,tmp.c_str(),this);    }    if (recvParams(msg,params))	return true;    return UART::error(EStopped);}// Append a parameter to a buffer// Truncate it or set error if fail is true and parameter length exceeds maxLen// Return: 0 if the parameter is missing//         -1 if the parameter is too long//         1 on successint appendParam(ObjList& msg, NamedList& params, unsigned char value,	unsigned char maxLen, bool fail){    NamedString* ns = params.getParam(lookup(value,ETSIModem::s_msgParams));    if (!ns)	return 0;    unsigned char len = ns->length();    if (len > maxLen) {	if (fail) {	    params.setParam("error",ns->name() + "-too-long");	    return -1;	}	len = maxLen;    }    DataBlock* data = new DataBlock;    unsigned char a[2] = {value,len};    FSKModem::addRaw(*data,a,sizeof(a));    FSKModem::addRaw(*data,(void*)ns->c_str(),len);    msg.append(data);    return 1;}// Append a parameter to a buffer from a list or dictionaryvoid appendParam(ObjList& msg, NamedList& params, unsigned char value,	TokenDict* dict, unsigned char defValue){    unsigned char a[3] = {value,1};    const char* name = lookup(value,ETSIModem::s_msgParams);    a[2] = lookup(params.getValue(name),dict,defValue);    msg.append(new DataBlock(a,sizeof(a)));}// Create a buffer containing the byte representation of a message to be sent//  and another one with the headerbool ETSIModem::createMsg(NamedList& params, DataBlock& data){    int type = lookup(params,s_msg);    switch (type) {	case MsgCallSetup:	    break;	case MsgMWI:	case MsgCharge:	case MsgSMS:	    Debug(this,DebugStub,"Create message '%s' not implemented [%p]",		params.c_str(),this);	    return false;	default:	    Debug(this,DebugNote,"Can't create unknown message '%s' [%p]",		params.c_str(),this);	    return false;    }    ObjList msg;    bool fail = !params.getBoolValue("force-send",true);    // DateTime - ETSI EN 300 659-3 - 5.4.1    String datetime = params.getValue("datetime");    unsigned char dt[4];    bool ok = false;    if (datetime.isBoolean())	if (datetime.toBoolean())	    ok = getDateTime(dt);	else ;    else	ok = getDateTime(dt,&datetime);    if (ok) {	DataBlock* dtParam = new DataBlock(0,10);	unsigned char* d = (unsigned char*)dtParam->data();	d[0] = DateTime;	d[1] = 8;	// Set date and time: %.2d%.2d%.2d%.2d month:day:hour:minute	for (int i = 0, j = 2; i < 4; i++, j += 2) {	    d[j] = '0' + dt[i] / 10;	    d[j+1] = '0' + dt[i] % 10;	}	msg.append(dtParam);    }    else	DDebug(this,DebugInfo,"Can't set datetime parameter from '%s' [%p]",	    datetime.c_str(),this);    // CallerId/CallerIdReason - ETSI EN 300 659-3 - 5.4.2: Max caller id 20    // Parameter is missing: append reason (default caller absence: 0x4f: unavailable)    int res = appendParam(msg,params,CallerId,20,fail);    if (res == -1)	return false;    if (!res)	appendParam(msg,params,CallerIdReason,s_dict_callerAbsence,0x4f);    // CallerName/CallerNameReason - ETSI EN 300 659-3 - 5.4.5: Max caller name 50    // Parameter is missing: append reason (default callername absence: 0x4f: unavailable)    res = appendParam(msg,params,CallerName,50,fail);    if (res == -1)	return false;    if (!res)	appendParam(msg,params,CallerNameReason,s_dict_callerAbsence,0x4f);    // Build message    unsigned char len = 0;    unsigned char hdr[2] = {type};    data.assign(&hdr,sizeof(hdr));    for (ObjList* o = msg.skipNull(); o; o = o->skipNext()) {	DataBlock* msgParam = static_cast<DataBlock*>(o->get());	if (len + msgParam->length() > 255) {	    if (!fail) {		Debug(this,DebugNote,"Trucating %s message length to %u bytes [%p]",		    params.c_str(),data.length(),this);		break;	    }	    params.setParam("error","message-too-long");	    return false;	}	len += msgParam->length();	data += *msgParam;    }    if (!len) {	params.setParam("error","empty-message");	return false;    }    unsigned char* buf = ((unsigned char*)(data.data()));    buf[1] = len;    m_chksum = 0;    for (unsigned int i = 0; i < data.length(); i++)	m_chksum += buf[i];    unsigned char crcVal = 256 - (m_chksum & 0xff);    FSKModem::addRaw(data,&crcVal,1);    return true;}// Change the state of this ETSI modemvoid ETSIModem::changeState(State newState){    if (m_state == newState)	return;    XDebug(this,DebugInfo,"ETSI changed state from %s to %s [%p]",	lookup(m_state,s_etsiState),lookup(newState,s_etsiState),this);    m_state = newState;}/** * UART */#ifdef XDEBUGstatic TokenDict s_uartState[] = {    {"Idle",   UART::Idle},    {"Start",  UART::BitStart},    {"Data",   UART::BitData},    {"Parity", UART::BitParity},    {"Stop",   UART::BitStop},    {"Error",  UART::UARTError},    {0,0}};#endifTokenDict UART::s_errors[] = {    {"framing",      UART::EFraming},    {"parity",       UART::EParity},    {"chksum",       UART::EChksum},    {"invalid-data", UART::EInvalidData},    {"unknown",      UART::EUnknown},    {"terminated",   UART::EStopped},    {"",             UART::ENone},    {0,0}};UART::UART(State state, const NamedList& params, const char* name)    : m_modem(params,this),    m_state(Idle),    m_error(ENone),    m_parity(0),    m_expectedParity(false),    m_accumulator(8){    debugName(name);    unsigned char dataBits = params.getIntValue("databits",8);    if (dataBits < 1 || dataBits > 8)	dataBits = 8;    m_accumulator.dataBits(dataBits);    m_parity = params.getIntValue("parity");    reset(state);}void UART::reset(State st){    changeState(st);    m_error = ENone;    m_modem.reset();    m_accumulator.reset();}// Push a bit of data into this UART// Return false to stop feeding databool UART::recvBit(bool value){#ifdef XDEBUG    Debug(this,DebugAll,"recvBit(%c) state=%s [%p]",	value?'1':'0',lookup(m_state,s_uartState),this);#endif    int res = 0;    switch (m_state) {	case Idle:	    res = m_accumulator.accumulate(value);	    if (res & 0xffffff00)		return true;	    res = idleRecvByte((unsigned char)res);	    if (res < 0)		return error(EUnknown);	    if (res)		changeState(BitStart);	    break;	case BitData:	    res = m_accumulator.accumulate(value);	    if (res & 0xffffff00)		return true;	    if (recvByte((unsigned char)res))		if (!m_parity)		    changeState(BitStop);		else {		    // TODO: get parity and set the expected one		    changeState(BitParity);		}	    else		return error(EUnknown);	    break;	case BitStart:	    if (!value)		changeState(BitData);	    break;	case BitStop:	    if (value)		changeState(BitStart);	    else		return error(EFraming);	    break;	case BitParity:	    if (value == m_expectedParity)		changeState(BitStop);	    else		return error(EParity);	    break;	default:	    return false;    }    return true;}// Set error statebool UART::error(Error e){    changeState(UARTError);    if (m_error == ENone) {	m_error = e;	if (m_error != EStopped)	    Debug(this,DebugNote,"Error detected: %u '%s' [%p]",		m_error,lookup(m_error,s_errors),this);    }    return false;}// Change the state of this UARTvoid UART::changeState(State newState){    if (m_state == newState)	return;#ifdef XDEBUG    Debug(this,DebugAll,"UART changed state from %s to %s [%p]",	lookup(m_state,s_uartState),lookup(newState,s_uartState),this);#endif    m_state = newState;}/* vi: set ts=8 sw=4 sts=4 noet: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -