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

📄 sms_cb.c

📁 Linux下gsm/gprs modem的看守程序。支持短信发送与接受。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* gsmd SMS functions * * (C) 2006-2007 by OpenMoko, Inc. * Written by Harald Welte <laforge@openmoko.org> * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <sys/un.h>#include "gsmd.h"#include <gsmd/gsmd.h>#include <gsmd/usock.h>#include <gsmd/select.h>#include <gsmd/atcmd.h>#include <gsmd/usock.h>#include <gsmd/unsolicited.h>#include <gsmd/sms.h>#include <gsmd/talloc.h>#include <gsmd/extrsp.h>static const char *ts0705_memtype_name[] = {	[GSM0705_MEMTYPE_NONE]		= "NONE",	[GSM0705_MEMTYPE_BROADCAST]	= "BM",	[GSM0705_MEMTYPE_ME_MESSAGE]	= "ME",	[GSM0705_MEMTYPE_MT]		= "MT",	[GSM0705_MEMTYPE_SIM]		= "SM",	[GSM0705_MEMTYPE_TA]		= "TA",	[GSM0705_MEMTYPE_SR]		= "SR",};static inline int parse_memtype(char *memtype){	int i;	for (i = 0; i < ARRAY_SIZE(ts0705_memtype_name); i++) {		if (!strcmp(ts0705_memtype_name[i], memtype))			return i;	}	return GSM0705_MEMTYPE_NONE;}static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	struct gsmd_sms_list msg;	int i, idx, stat, len, cr;	u_int8_t pdu[SMS_MAX_PDU_SIZE];	if (cmd->ret && cmd->ret != -255)		return 0;	/* TODO: Send a response */	/* FIXME: TEXT mode */	if (			sscanf(resp, "+CMGL: %i,%i,,%i\n%n",				&idx, &stat, &len, &cr) < 3 &&			sscanf(resp, "+CMGL: %i,%i,\"%*[^\"]\",%i\n%n",				&idx, &stat, &len, &cr) < 3)		return -EINVAL;	/* TODO: Send a response */	if (len > 164)		return -EINVAL;	/* TODO: Send a response */	msg.index = idx;	msg.stat = stat;	msg.is_last = (cmd->ret == 0);	for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' &&			i < SMS_MAX_PDU_SIZE; i ++) {		if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) {			gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);			return -EINVAL;	/* TODO: Send a response */		}		cr += 2;	}	if (sms_pdu_to_msg(&msg, pdu, len, i)) {		gsmd_log(GSMD_DEBUG, "malformed PDU\n");		return -EINVAL;	/* TODO: Send a response */	}	return gsmd_ucmd_submit(gu, GSMD_MSG_SMS, GSMD_SMS_LIST,			cmd->id, sizeof(msg), &msg);}static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	struct gsmd_sms_list msg;	int i, stat, len, cr;	u_int8_t pdu[SMS_MAX_PDU_SIZE];	const char *colon;	if (cmd->ret)		return 0;	/* TODO: Send a response */	/* FIXME: TEXT mode */	if (			sscanf(resp, "+CMGR: %i,,%i\n%n",				&stat, &len, &cr) < 2 &&                        sscanf(resp, "+CMGR: %i,\"%*[^\"]\",%i\n%n",				&stat, &len, &cr) < 2)		return -EINVAL;	/* TODO: Send a response */	if (len > 164)		return -EINVAL;	/* TODO: Send a response */	msg.index = 0;	colon = strchr(cmd->buf, '=');        /* get a correct message index value on reading a SMS */	if (!strncmp(cmd->buf, "AT+CMGR", 7) && colon) 		msg.index = atoi(colon+1);	msg.stat = stat;	msg.is_last = 1;	for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' &&			i < SMS_MAX_PDU_SIZE; i ++) {		if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) {			gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);			return -EINVAL;	/* TODO: Send a response */		}		cr += 2;	}	if (sms_pdu_to_msg(&msg, pdu, len, i)) {		gsmd_log(GSMD_DEBUG, "malformed PDU\n");		return -EINVAL;	}	return gsmd_ucmd_submit(gu, GSMD_MSG_SMS, GSMD_SMS_READ,			cmd->id, sizeof(msg), &msg);}static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	int msgref;	if (cmd->ret == 0 || cmd->ret == -255) {		if (sscanf(resp, "+CMGS: %i", &msgref) < 1)			msgref = -EINVAL;	} else		msgref = -cmd->ret;	return gsmd_ucmd_submit(ctx, GSMD_MSG_SMS, GSMD_SMS_SEND,			cmd->id, sizeof(msgref), &msgref);}static int sms_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	int result;	if (cmd->ret == 0) {		if (sscanf(resp, "+CMGW: %i", &result) < 1)			result = -EINVAL;	} else		result = -cmd->ret;	return gsmd_ucmd_submit(ctx, GSMD_MSG_SMS, GSMD_SMS_WRITE,			cmd->id, sizeof(result), &result);}static int sms_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	int result = cmd->ret;	return gsmd_ucmd_submit(ctx, GSMD_MSG_SMS, GSMD_SMS_DELETE,			cmd->id, sizeof(result), &result);}static int usock_cpms_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	struct gsmd_ucmd *ucmd = ucmd_alloc(sizeof(struct gsmd_sms_storage));	struct gsmd_sms_storage *gss = (typeof(gss)) ucmd->buf;	char buf[3][3];	DEBUGP("entering(cmd=%p, gu=%p)\n", cmd, gu);	if (!ucmd)		return -ENOMEM;	ucmd->hdr.version = GSMD_PROTO_VERSION;	ucmd->hdr.msg_type = GSMD_MSG_SMS;	ucmd->hdr.msg_subtype = GSMD_SMS_GET_MSG_STORAGE;	ucmd->hdr.len = sizeof(struct gsmd_sms_storage);	ucmd->hdr.id = cmd->id;	if (sscanf(resp, "+CPMS: \"%2[A-Z]\",%hi,%hi,"				"\"%2[A-Z]\",%hi,%hi,\"%2[A-Z]\",%hi,%hi",				buf[0], &gss->mem[0].used, &gss->mem[0].total,				buf[1], &gss->mem[1].used, &gss->mem[1].total,				buf[2], &gss->mem[2].used, &gss->mem[2].total)			< 9) {		talloc_free(ucmd);		return -EINVAL;	/* TODO: Send a response */	}	gss->mem[0].memtype = parse_memtype(buf[0]);	gss->mem[1].memtype = parse_memtype(buf[1]);	gss->mem[2].memtype = parse_memtype(buf[2]);	usock_cmd_enqueue(ucmd, gu);	return 0;}static int usock_get_smsc_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_addr ga;	if (sscanf(resp, "+CSCA: \"%31[^\"]\",%hhi",				ga.number, &ga.type) < 2)		return -EINVAL;	/* TODO: Send a response */	return gsmd_ucmd_submit(ctx,			GSMD_MSG_SMS, GSMD_SMS_GET_SERVICE_CENTRE,			cmd->id, sizeof(ga), &ga);}static const char *gsmd_cmgl_stat[] = {	"REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL",};/* main unix socket Short Message receiver */int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len){	/* FIXME: TEXT mode support!!  */	struct gsmd_atcmd *cmd = NULL;	struct gsmd_sms_delete *gsd;	struct gsmd_sms_submit *gss;	struct gsmd_sms_write *gsw;	struct gsmd_addr *ga;	enum ts0705_mem_type *storage;	int *stat, *index;	int atcmd_len;	char buf[1024];	switch (gph->msg_subtype) {	case GSMD_SMS_LIST:		if(len < sizeof(*gph) + sizeof(int))			return -EINVAL;		stat = (int *) ((void *)gph + sizeof(*gph));		if (*stat < 0 || *stat > 4)			return -EINVAL;		if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT)			atcmd_len = sprintf(buf, "AT+CMGL=\"%s\"",					gsmd_cmgl_stat[*stat]);		else			atcmd_len = sprintf(buf, "AT+CMGL=%i", *stat);		cmd = atcmd_fill(buf, atcmd_len + 1,				&sms_list_cb, gu, gph->id, NULL);		break;	case GSMD_SMS_READ:		if(len < sizeof(*gph) + sizeof(int))			return -EINVAL;		index = (int *) ((void *)gph + sizeof(*gph));		atcmd_len = sprintf(buf, "AT+CMGR=%i", *index);		cmd = atcmd_fill(buf, atcmd_len + 1,				&sms_read_cb, gu, gph->id, NULL);		break;	case GSMD_SMS_SEND:		if (len < sizeof(*gph) + sizeof(*gss))			return -EINVAL;		gss = (struct gsmd_sms_submit *) ((void *) gph + sizeof(*gph));		if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) {			atcmd_len = sprintf(buf, "AT+CMGS=\"%s\"\n%.*s",					gss->addr.number,					gss->payload.length,					gss->payload.data);	/* FIXME */		} else {			atcmd_len = sprintf(buf, "AT+CMGS=%i\n",					sms_pdu_make_smssubmit(NULL, gss) - 1);			atcmd_len += sms_pdu_make_smssubmit(buf + atcmd_len,					gss) * 2;		}		buf[atcmd_len ++] = 26;	/* ^Z ends the message */		buf[atcmd_len ++] = 0;		cmd = atcmd_fill(buf, atcmd_len, &sms_send_cb, gu, gph->id, NULL);		break;	case GSMD_SMS_WRITE:		if (len < sizeof(*gph) + sizeof(*gsw))			return -EINVAL;		gsw = (struct gsmd_sms_write *) ((void *) gph + sizeof(*gph));		if (gsw->stat > 4)			return -EINVAL;		if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) {			atcmd_len = sprintf(buf, "AT+CMGW=\"%s\"\n%.*s",					gsw->sms.addr.number,					gsw->sms.payload.length,					gsw->sms.payload.data);	/* FIXME */		} else {			atcmd_len = sprintf(buf, "AT+CMGW=%i,%i\n",					sms_pdu_make_smssubmit(NULL,						&gsw->sms) - 1, gsw->stat);			atcmd_len += sms_pdu_make_smssubmit(buf + atcmd_len,					&gsw->sms) * 2;		}		buf[atcmd_len ++] = 26;	/* ^Z ends the message */		buf[atcmd_len ++] = 0;		cmd = atcmd_fill(buf, atcmd_len, &sms_write_cb, gu, gph->id, NULL);		break;	case GSMD_SMS_DELETE:		if(len < sizeof(*gph) + sizeof(*gsd))			return -EINVAL;		gsd = (struct gsmd_sms_delete *) ((void *)gph + sizeof(*gph));		atcmd_len = sprintf(buf, "AT+CMGD=%d,%d",				gsd->index, gsd->delflg);		cmd = atcmd_fill(buf, atcmd_len + 1,				&sms_delete_cb, gu, gph->id, NULL);		break;	case GSMD_SMS_GET_MSG_STORAGE:		cmd = atcmd_fill("AT+CPMS?", 8 + 1, usock_cpms_cb, gu, 0, NULL);		break;	case GSMD_SMS_SET_MSG_STORAGE:		if (len < sizeof(*gph) + 3 * sizeof(enum ts0705_mem_type))			return -EINVAL;		storage = (enum ts0705_mem_type *)			((void *) gph + sizeof(*gph));		atcmd_len = sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"",				ts0705_memtype_name[storage[0]],

⌨️ 快捷键说明

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