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

📄 unsolicited.c

📁 Linux下gsm/gprs modem的看守程序。支持短信发送与接受。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* gsmd unsolicited message handling * * (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 <unistd.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include "gsmd.h"#include <gsmd/usock.h>#include <gsmd/event.h>#include <gsmd/extrsp.h>#include <gsmd/ts0707.h>#include <gsmd/unsolicited.h>#include <gsmd/talloc.h>#include <gsmd/sms.h>struct gsmd_ucmd *usock_build_event(u_int8_t type, u_int8_t subtype, u_int16_t len){	struct gsmd_ucmd *ucmd = ucmd_alloc(len);	if (!ucmd)		return NULL;	ucmd->hdr.version = GSMD_PROTO_VERSION;	ucmd->hdr.msg_type = type;	ucmd->hdr.msg_subtype = subtype;	ucmd->hdr.len = len;	return ucmd;}static struct gsmd_ucmd *ucmd_copy(const struct gsmd_ucmd *orig){	struct gsmd_ucmd *copy = ucmd_alloc(orig->hdr.len);	if (copy)		memcpy(copy, orig, orig->hdr.len);	return copy;}int usock_evt_send(struct gsmd *gsmd, struct gsmd_ucmd *ucmd, u_int32_t evt){	struct gsmd_user *gu;	int num_sent = 0;	DEBUGP("entering evt=%u\n", evt);	llist_for_each_entry(gu, &gsmd->users, list) {		if (gu->subscriptions & (1 << evt)) {			if (num_sent == 0)				usock_cmd_enqueue(ucmd, gu);			else {				struct gsmd_ucmd *cpy = ucmd_copy(ucmd);				if (!cpy) {					fprintf(stderr, 						"can't allocate memory for "						"copy of ucmd\n");					return num_sent;				}				usock_cmd_enqueue(cpy, gu);			}			num_sent++;		}	}	if (num_sent == 0)		talloc_free(ucmd);	return num_sent;}static void state_ringing_timeout(struct gsmd_timer *timer, void *opaque){	struct gsmd *gsmd = (struct gsmd *) opaque;	struct gsmd_ucmd *ucmd;	struct gsmd_evt_auxdata *aux;	gsmd->dev_state.ring_check = 0;	gsmd_timer_free(timer);	/* Update state */	if (!gsmd->dev_state.ringing)		return;	gsmd->dev_state.ringing = 0;	gsmd_log(GSMD_INFO, "an incoming call timed out\n");	/* Generate a timeout event */	ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_IN_CALL,			sizeof(struct gsmd_evt_auxdata));		if (!ucmd)		goto err;	aux = (struct gsmd_evt_auxdata *) ucmd->buf;	aux->u.call.type = GSMD_CALL_TIMEOUT;	if (usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_CALL) < 0)		goto err;	return;err:	gsmd_log(GSMD_ERROR, "event generation failed\n");}#define GSMD_RING_MAX_JITTER (200 * 1000)	/* 0.2 s */static void state_ringing_update(struct gsmd *gsmd){	struct timeval tv;	if (gsmd->dev_state.ring_check)		gsmd_timer_unregister(gsmd->dev_state.ring_check);	/* Update state */	gsmd->dev_state.ringing = 1;	tv.tv_sec = 1;	tv.tv_usec = GSMD_RING_MAX_JITTER;	if (gsmd->dev_state.ring_check) {		gsmd->dev_state.ring_check->expires = tv;		gsmd_timer_register(gsmd->dev_state.ring_check);	} else		gsmd->dev_state.ring_check = gsmd_timer_create(&tv,				&state_ringing_timeout, gsmd);}static int ring_parse(const char *buf, int len, const char *param,		      struct gsmd *gsmd){        struct gsmd_ucmd *ucmd;	struct gsmd_evt_auxdata *aux;        state_ringing_update(gsmd);        ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_IN_CALL,                        sizeof(struct gsmd_evt_auxdata));	/* FIXME: generate ring event */	if (!ucmd)		return -ENOMEM;	aux = (struct gsmd_evt_auxdata *) ucmd->buf;	aux->u.call.type = GSMD_CALL_UNSPEC;	return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_CALL);}static int cring_parse(const char *buf, int len, const char *param, struct gsmd *gsmd){	struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_IN_CALL,					     sizeof(struct gsmd_evt_auxdata));	struct gsmd_evt_auxdata *aux;	if (!ucmd)		return -ENOMEM;	aux = (struct gsmd_evt_auxdata *) ucmd->buf;	if (!strcmp(param, "VOICE")) {		/* incoming voice call */		aux->u.call.type = GSMD_CALL_VOICE;	} else if (!strcmp(param, "SYNC")) {		aux->u.call.type = GSMD_CALL_DATA_SYNC;	} else if (!strcmp(param, "REL ASYNC")) {		aux->u.call.type = GSMD_CALL_DATA_REL_ASYNC;	} else if (!strcmp(param, "REL SYNC")) {		aux->u.call.type = GSMD_CALL_DATA_REL_SYNC;	} else if (!strcmp(param, "FAX")) {		aux->u.call.type = GSMD_CALL_FAX;	} else if (!strncmp(param, "GPRS ", 5)) {		/* FIXME: change event type to GPRS */		talloc_free(ucmd);		return 0;	} else {                aux->u.call.type = GSMD_CALL_UNSPEC;        }	/* FIXME: parse all the ALT* profiles, Chapter 6.11 */	return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_CALL);}/* Chapter 7.2, network registration */static int creg_parse(const char *buf, int len, const char *param,		      struct gsmd *gsmd){	const char *comma = strchr(param, ',');	struct gsmd_ucmd *ucmd;	struct gsmd_evt_auxdata *aux;	int prev_registered = gsmd->dev_state.registered;	int state;	char *end;	state = strtol(param, &end, 10);	if (!(end > param)) {		gsmd_log(GSMD_ERROR, "Bad +CREG format, not updating state\n");		return -EINVAL;	}	/* Update our knowledge about our state */	gsmd->dev_state.registered =		(state == GSMD_NETREG_REG_HOME ||		 state == GSMD_NETREG_REG_ROAMING);	/* Intialise things that depend on network registration */	if (gsmd->dev_state.registered && !prev_registered) {		sms_cb_network_init(gsmd);	}	/* Notify clients */	ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_NETREG,			sizeof(struct gsmd_evt_auxdata));	if (!ucmd)		return -ENOMEM;	aux = (struct gsmd_evt_auxdata *) ucmd->buf;	aux->u.netreg.state = atoi(param);	if (comma) {		/* we also have location area code and cell id to parse (hex) */		aux->u.netreg.lac = strtoul(comma+2, NULL, 16);		comma = strchr(comma+1, ',');		if (!comma)			return -EINVAL;		aux->u.netreg.ci = strtoul(comma+2, NULL, 16);	} else		aux->u.netreg.lac = aux->u.netreg.ci = 0;	return usock_evt_send(gsmd, ucmd, GSMD_EVT_NETREG);}/* Chapter 7.11, call waiting */static int ccwa_parse(const char *buf, int len, const char *param,		      struct gsmd *gsmd){	struct gsmd_evt_auxdata *aux;	struct gsm_extrsp *er;	struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_CALL_WAIT,					     sizeof(struct gsmd_evt_auxdata));		if (!ucmd)		return -ENOMEM;	aux = (struct gsmd_evt_auxdata *) ucmd->buf;		er = extrsp_parse(gsmd_tallocs, param);	if ( !er ) 		return -ENOMEM;	if ( er->num_tokens == 5 &&			er->tokens[0].type == GSMD_ECMD_RTT_STRING &&			er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC &&			er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC &&			er->tokens[3].type == GSMD_ECMD_RTT_EMPTY &&			er->tokens[4].type == GSMD_ECMD_RTT_NUMERIC ) {		/*		 * <number>,<type>,<class>,[<alpha>][,<CLI validity>]		 */				strcpy(aux->u.ccwa.addr.number, er->tokens[0].u.string);		aux->u.ccwa.addr.type = er->tokens[1].u.numeric;		aux->u.ccwa.classx = er->tokens[2].u.numeric;		aux->u.ccwa.alpha[0] = '\0';		aux->u.ccwa.cli = er->tokens[4].u.numeric; 	} 	else if ( er->num_tokens == 5 &&			er->tokens[0].type == GSMD_ECMD_RTT_STRING &&			er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC &&			er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC &&			er->tokens[3].type == GSMD_ECMD_RTT_STRING &&			er->tokens[4].type == GSMD_ECMD_RTT_NUMERIC ) {		/*		 * <number>,<type>,<class>,[<alpha>][,<CLI validity>]		 */				strcpy(aux->u.ccwa.addr.number, er->tokens[0].u.string);		aux->u.ccwa.addr.type = er->tokens[1].u.numeric;		aux->u.ccwa.classx = er->tokens[2].u.numeric;		strcpy(aux->u.ccwa.alpha, er->tokens[3].u.string);		aux->u.ccwa.cli = er->tokens[4].u.numeric; 	}	else {		DEBUGP("Invalid Input : Parse error\n");		return -EINVAL;	}	return usock_evt_send(gsmd, ucmd, GSMD_EVT_CALL_WAIT);}/* Chapter 7.14, unstructured supplementary service data */static int cusd_parse(const char *buf, int len, const char *param,		      struct gsmd *gsmd){	/* FIXME: parse */	return 0;}/* Chapter 7.15, advise of charge */static int cccm_parse(const char *buf, int len, const char *param,		      struct gsmd *gsmd){	/* FIXME: parse */	return 0;}/* Chapter 10.1.13, GPRS event reporting */static int cgev_parse(const char *buf, int len, const char *param,		      struct gsmd *gsmd){

⌨️ 快捷键说明

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