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

📄 sms.c

📁 中文短信的编解码
💻 C
📖 第 1 页 / 共 2 页
字号:

/*
 *	GSM短信
 *	by xxsg
 *	2006-6-19 10:29
*/

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#include "include/sms.h"
/* pdu_cn.c */
extern const unsigned short gb2unicode_0xa1_0xa9[];
extern const unsigned short gb2unicode_0xb0_0xf7[];
extern const unsigned short unicode2gb_0x4E00_0x9FA0[];
extern const unsigned short unicode2gb_0x00A4_0x0451[];
extern const unsigned short unicode2gb_0x2015_0x2642[];
extern const unsigned short unicode2gb_0x3000_0x3229[];
extern const unsigned short unicode2gb_0xFF01_0xFFE5[];
/* pdu_cn.c */

int SMS_pdu_ctl(SMS_INFO * sm, int pdu_key, char * para)
{
	if((NULL == sm) || (NULL == para))
	{
		return ERROR;
	}
	switch(pdu_key)
	{
	case SMS_PDU_CPY:
		{
			int	   len_pdu;
			
			if(32 < (len_pdu = strlen(para)))
			{
				return ERROR;
			}
			strcpy(sm->pdu_buf,para);
			sm->len_head = len_pdu;
			sm->len_pdu = len_pdu;
		}
		break;
	case SMS_PDU_SMSC:
		{
			AT_CMD 	at_send = {
				5,100000,NULL,(ATR_OK)
			};
			char at_str[100];
			
			sprintf(at_str,"AT+CSCA=\"%s\"\r",para);
			at_send.at_str = at_str;
			return at_set(sm->modem,&at_send);
		}
		break;
	case SMS_PDU_OCTET:
		bcopy(para,&(sm->pdu_buf[2]),2);
		break;
	case SMS_PDU_MR:
		bcopy(para,&(sm->pdu_buf[4]),2);
		break;
	case SMS_PDU_DA:
		{
			char * p_pdu;
			int	   len_pdu;
			int	   len_para;
			char   bak[7];
			char   ch;
			
			if(20 < (len_para = strlen(para)))
			{
				return ERROR;
			}
			p_pdu = sm->pdu_buf;
			len_pdu = sm->len_head;
			bcopy((p_pdu+len_pdu-6),bak,6);

			len_para = strlen(para);
			if(*para == '+')
			{
				para++;
				len_pdu = sprintf((p_pdu+6),"%02X91",len_para-1) + 6;
			}
			else if(11 == len_para)
			{
				len_pdu = sprintf((p_pdu+6),"%02X9168",len_para+2) + 6;
			}
			else
			{
				len_pdu = sprintf((p_pdu+6),"%02XA1",len_para) + 6;
			}
			while(1)
			{
				ch = *para++;
				if(ch)
				{
					p_pdu[len_pdu+1] = ch;
				}
				else
				{
					break;
				}
				ch = *para++;
				if(ch)
				{
					p_pdu[len_pdu] = ch;
					len_pdu += 2;
				}
				else
				{
					p_pdu[len_pdu] = 'F';
					len_pdu += 2;
					break;
				}
			}
			bcopy(bak,(p_pdu+len_pdu),6);
			len_pdu += 6;
			sm->len_head = len_pdu;
		}
		break;
	case SMS_PDU_PID:
		bcopy(para,&(sm->pdu_buf[sm->len_head-6]),2);
		break;
	case SMS_PDU_DCS:
		bcopy(para,&(sm->pdu_buf[sm->len_head-4]),2);
		break;
	case SMS_PDU_VP:
		bcopy(para,&(sm->pdu_buf[sm->len_head-2]),2);
		break;
	default:
		return ERROR;
	}
	sm->pdu_buf[sm->len_head] = 0;
	printf("%s\n",sm->pdu_buf);
	return OK;
}

/* 读取短信的数目 */
int SMS_check_recv(SMS_INFO * sms)
{
	AT_CMD 	at_send = {
		3,100000,"AT+CPMS?\r",(ATR_RET|ATR_OK)
	};
	AT_RX_BUF * p_rx;
	int sms_num = 0;
	
	if(OK == at_set(sms->modem,&at_send))
	{
		p_rx = at_get_rxbuf(sms->modem,ATR_RET);
		if((NULL != p_rx) && (0 == bcmp(p_rx->buf,"+CPMS:",6)))
		{
			char * p;

			p = p_rx->buf + 6;
			while((*p < '0') || (*p > '9'))
			{
				p++;
			}
			while((*p >= '0') && (*p <= '9'))
			{
				sms_num *= 10;
				sms_num += *p - '0';
				p++;
			}
			while((*p < '0') || (*p > '9'))
			{
				p++;
			}
			sms->max_no = 0;
			while((*p >= '0') && (*p <= '9'))
			{
				sms->max_no *= 10;
				sms->max_no += *p - '0';
				p++;
			}
		}
		else
		{
			sg_dbg("+CPMS:--get fail");
		}
	}
	else
	{
		sg_dbg("AT+CPMS?--return fail");
	}

	return sms_num;
}

/*
 *	函数名:		SMS_Init
 *	描述:		初始化函数
 *	入口参数: 
 *				int 	i_In_FD				串口句柄
 *	返回值:
 *				OK		成功
 *				ERROR	不成功, 可由*p_ul_Out_Resp 指示相应的出错类型
 */
SMS_INFO * SMS_Init(int fd_com)
{
	static AT_CMD 	sms_at_init[] = {
		{ 30,	100000,	"ATE0\r"				,ATR_OK},
#if 1
		{ 30,	100000,	"AT\r"					,ATR_OK},
		{ 30,	100000,	"AT+CNMI=2,1,0,0,1\r" 	,ATR_OK},
		{ 30,	100000,	"AT+CSDH=1\r"			,ATR_OK},
#endif
		{ 30,	100000,	"AT+CMGF=0\r"			,ATR_OK},
		{ 30,	100000,	"AT+CSCS=\"GSM\"\r"		,ATR_OK}
	};
	int i;
	SMS_INFO * sms;

	sms = (SMS_INFO *) calloc(1,sizeof(SMS_INFO));
	if(NULL == sms)
	{
		sg_dbg("calloc sms");
		return NULL;
	}
	SMS_pdu_ctl(sms,SMS_PDU_CPY,"0011000D91683100932183F70004A7");
	if(NULL == (sms->modem = at_modem_init(fd_com)))
	{
		free(sms);
		return NULL;
	}
	for(i=0;i<(sizeof(sms_at_init)/sizeof(AT_CMD));i++)
	{
		if(ERROR == at_set(sms->modem,&sms_at_init[i]))
		{
#if 1
			SMS_Exit(sms);
			return NULL;
#else	/* for debug */
			break;
#endif
		}
	}
	printf("modem OK!\n");

	return sms;
}

/*
 *	函数名:		SMS_Exit
 *	描述:		短信退出函数
 *	返回值:
 *				OK		成功
 *				ERROR	不成功, 可由*p_ul_Out_Resp 指示相应的出错类型
 */
STATUS SMS_Exit(SMS_INFO * sms)
{
	free(sms->modem);
	free(sms);
	
	return OK;
}

int SMS_pdu_make_gb2312(SMS_INFO * sms,unsigned char * src)
{
	unsigned char * pdu;
	unsigned short unicode,tmp;
	int cnt,len,max;
	unsigned char chH,chL;

	len = sms->len_pdu;
	max = sms->len_head + 282;
	pdu = sms->pdu_buf;
	for(cnt=0;len<max;)
	{
		chH = src[cnt++];
		if(chH < 0x80)
		{
			if(0 != chH)
			{
				unicode = chH;
			}
			else
			{
				break;
			}
		}
		else
		{
			if((chH >= 0xb0) && (chH <= 0xf7))
			{
				chL = src[cnt++];
				if((chL >= 0xa1) && (chL != 0xff))
				{
					chH -= 0xb0;
					chL -= 0xa1;
					tmp = chH;
					tmp *= 94;
					tmp += chL;
					unicode = gb2unicode_0xb0_0xf7[tmp];
				}
				else
				{
					unicode = 0x25A1;
				}
			}
			else if((chH >= 0xa0) && (chH <= 0xa9))
			{
				chL = src[cnt++];
				if((chL >= 0xa1) && (chL != 0xff))
				{
					chH -= 0xa1;
					chL -= 0xa1;
					tmp = chH;
					tmp *= 94;
					tmp += chL;
					unicode = gb2unicode_0xa1_0xa9[tmp];
				}
				else
				{
					unicode = 0x25A1;
				}
			}
			else
			{
				unicode = 0x25A1;
			}
		}
		len += sprintf(&(pdu[len]),"%04X",unicode);
	}
	sms->len_pdu = len;
	len = sms->len_head + 2;
	chH = pdu[len];
	sprintf(&(pdu[sms->len_head]),"%02X",(sms->len_pdu - len)/2);
	pdu[len] = chH;
	
	return cnt;
}

int SMS_pdu_make_text(SMS_INFO * sms,unsigned char * src)
{
	unsigned char * pdu;
	unsigned short ush,tmp;
	unsigned char uch;
	int cnt,len,max;
	const unsigned short tab[8] = {0x0001,0x0080,0x0040,0x0020,0x0010,0x0008,0x0004,0x0002};

	len = sms->len_pdu;
	max = sms->len_head + 282;
	pdu = sms->pdu_buf;
	ush = 0;
	for(cnt=0;len<max;)
	{
		if((cnt&0x07) == 0)
		{
			if(0 == src[cnt])
			{
				break;
			}
			ush = src[cnt++]&0x7f;
		}
		if(0 == src[cnt])
		{
			len += sprintf(&(pdu[len]),"%02X",(ush & 0x00ff));
			break;
		}
		tmp = src[cnt]&0x7f;
		tmp *= tab[cnt&0x07];
		ush += tmp;
		len += sprintf(&(pdu[len]),"%02X",(ush & 0x00ff));
		ush /= 0x0100;
		cnt++;
	}
	sms->len_pdu = len;
	len = sms->len_head + 2;
	uch = pdu[len];
	sprintf(&(pdu[sms->len_head]),"%02X",cnt);
	pdu[len] = uch;
	
	return cnt;
}

int SMS_pdu_make_data(SMS_INFO * sms,unsigned char * src, int size)
{
	unsigned char * pdu;
	unsigned char uch;
	int cnt,len,max;

	len = sms->len_pdu;
	max = sms->len_head + 282;
	pdu = sms->pdu_buf;
	for(cnt=0;len<max;)
	{
		if(size > cnt)
		{
			len += sprintf(&(pdu[len]),"%02X",(src[cnt++]));
		}
		else
		{
			break;
		}
	}
	sms->len_pdu = len;
	len = sms->len_head + 2;
	uch = pdu[len];
	sprintf(&(pdu[sms->len_head]),"%02X",cnt);
	pdu[len] = uch;
	
	return cnt;
}

int SMS_pdu_cmgs(SMS_INFO * sms)
{
	int	len;
	char at_cmgs[20];
	AT_CMD 	at_send = {
		1,100000,NULL,ATR_NULL
	};
	
	if(sms == NULL)
	{
		sg_dbg("\nSMS_Send sms error!");
		return ERROR;
	}
	len = sms->len_pdu;
	
	sprintf(at_cmgs,"AT+CMGS=%d\r",((len-2)/2));
	at_send.at_str = &(at_cmgs[0]);
	at_set(sms->modem,&at_send);

	sms->pdu_buf[len++] = 0x1A;
	sms->pdu_buf[len] = 0;
	at_send.at_str = sms->pdu_buf;
	at_send.wait_sec = 5;

⌨️ 快捷键说明

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