C语言实现SMS短信PDU编码解码

3星 · 超过75%的资源 需积分: 9 25 下载量 62 浏览量 更新于2024-08-01 1 收藏 49KB DOC 举报
"这篇文章主要介绍了如何使用C语言编写短信编程代码,特别是涉及到PDU编码的7位编码和解码算法。" 在短信通信中,PDU(Protocol Data Unit,协议数据单元)是一种用于编码和传输短信的方式,尤其适用于GSM系统。在C语言中处理SMS短信,通常涉及到对字符进行7位编码和解码,因为GSM 7位编码集被广泛用于短信内容的传输。这种编码方式可以将ASCII字符集中的字符压缩到7位,从而节省存储和传输的空间。 7位编码函数`gsmEncode7bit`的工作原理如下: 1. 它接收一个源字符串指针`pSrc`,一个目标编码串指针`pDst`,以及源字符串长度`nSrcLength`。 2. 函数首先初始化计数器`nSrc`和`nDst`,用于跟踪源字符串和目标编码串的位置。 3. 使用一个循环处理源字符串的每个字节,将8个字节分为一组,压缩成7个字节。在每组中,第一个字节会被保存,待后续字节处理时使用。 4. 对于组内的其他字节,它们的右边部分与上一字节的残余数据相加,生成一个目标编码字节。同时,将该字节的左边部分作为新的残余数据保存。 5. 循环结束后,返回目标编码串的长度`nDst`。 7位解码函数`gsmDecode7bit`的步骤则相反: 1. 同样接收源编码串指针`pSrc`,目标字符串指针`pDst`,以及源编码串长度`nSrcLength`。 2. 初始化计数器`nSrc`,`nDst`,并设置组内字节序号`nByte`和残余数据`nLeft`。 3. 每7个字节一组,解压缩成8个字节的原始字符。循环处理源编码串,直到处理完所有数据。 4. 解码过程中,每组的第一个字节会与上一组的残余数据结合,形成完整的8位字节。然后将这8位字节拆分成两个7位的字符,分别存储到目标字符串中。 5. 循环结束后,返回目标字符串的长度`nDst`。 这两个函数是处理短信PDU编码的关键,它们允许C程序读取和构造PDU格式的短信,以便于在GSM网络中发送和接收短信。在实际应用中,这些函数通常会与AT命令结合使用,通过调制解调器或SIM卡接口与移动网络进行交互。理解并正确实施这些算法对于开发基于短信的通信应用程序至关重要。

解释下面代码static UINT8 libTXT2PDU( UINT8* msgData, UINT16 msgLen, UINT8* pTpdu, AtciMsgInfo *pAtSmsMessage, AtciCharacterSet chset_type ) { UINT8 offset = 0; UINT16 len=0; //CPUartLogPrintf("%s: enter", __FUNCTION__); //int i; //for(i=0;i<msgLen;i++) //CPUartLogPrintf("%s: msgData[%d] %d 0x%x", __FUNCTION__, i, msgData[i], msgData[i]); /* Copy the first octet */ /*SIMCom xiaokai.yang sync sms code @2023-02-06 begin*/ #ifdef FEATURE_SIMCOM_SMS char headbuf[PDU_HEAD_SIZE] = {0x05,0x00,0x03}; scCmssexInfoT* p_CmgsexInfo = (scCmssexInfoT*)getCmgsexInfoInd(); if(pAtSmsMessage->udhPresent) { pTpdu[ offset++ ] = (pAtSmsMessage->fo)|(0x1<<6); } else #endif /*SIMCom xiaokai.yang sync sms code @2023-02-06 end*/ pTpdu[ offset++ ] = pAtSmsMessage->fo; /* Message Reference */ pTpdu[ offset++ ] = pAtSmsMessage->msgRef; /* Originating Address (TP-OA) */ { UINT8 idx; UINT8 *data; data = pTpdu + offset; /* Set the Address Length octet */ *data++ = strlen( (char *)pAtSmsMessage->destAddr ); #ifdef FEATURE_SIMCOM_SMS PAL_LogIo(SC_MODULE_SMS,PAL_DBG_LEVEL_INFO,"destAddr [%s]",( (char *)pAtSmsMessage->destAddr )); #endif /* Format the TON/NPI octet */ *data++ = (UINT8)((pAtSmsMessage->addrType << 4) | pAtSmsMessage->addrPlan | 0x80); /* Format the BCD digits */ for ( idx = 0; idx < strlen( (char *)pAtSmsMessage->destAddr ); idx++ ) { libPutPackedBcd( data, idx, pAtSmsMessage->destAddr[ idx ], TRUE ); } /* check if we need to tack on a filler */ if( idx & 0x01 ) { /* Yup -- do it! , reversed nibbles */ libPutPackedBcd( data, idx, ATCI_BCD_FILLER, TRUE ); ++idx; } /* We're done -- update the PDU byte index */ offset += idx/2 + ATCI_SMS_BCD_POS; } /* Protocol Identifier (TP-PID) */ pTpdu[ offset++ ] = pAtSmsMessage->pid; /* Data Coding Scheme (TP-DCS) */ pTpdu[ offset++ ] = pAtSmsMessage->dcs; if(((pAtSmsMessage->fo&ATCI_TP_MTI_MASK)==ATCI_SMS_SUBMIT_MTI)&&((pAtSmsMessage->fo&ATCI_SMS_TP_VPF)==0x10)) { pTpdu[ offset++ ] = pAtSmsMessage->vp; } /*SIMCom xiaokai.yang sync sms code @2023-02-06 begin*/ #ifdef FEATURE_SIMCOM_SMS if(pAtSmsMessage->udhPresent) { headbuf[3] = p_CmgsexInfo->mr; headbuf[4] = p_CmgsexInfo->msg_total; headbuf[5] = p_CmgsexInfo->msg_seg; memmove(msgData+PDU_HEAD_SIZE,msgData,msgLen); memcpy(msgData, headbuf, PDU_HEAD_SIZE); msgLen+=PDU_HEAD_SIZE; } PAL_LogIo(SC_MODULE_SMS,PAL_DBG_LEVEL_INFO,"offset1 [%d],msgLen=%d",offset,msgLen);//274 #endif /*SIMCom xiaokai.yang sync sms code @2023-02-06 end*/ /* Now for the Message Data (TP-UDL + TP-UD) */ //ScShowDataByHex((char *)pTpdu, offset); //CPUartLogPrintf("[sms]msgLen=%d",msgLen); libMsgEncodeUserData( pAtSmsMessage->udhPresent, pAtSmsMessage->dcs, pTpdu, msgData, msgLen, offset, &len,chset_type); return len; }

2023-06-08 上传