usock.c.svn-base

来自「Linux下gsm/gprs modem的看守程序。支持短信发送与接受。」· SVN-BASE 代码 · 共 1,745 行 · 第 1/4 页

SVN-BASE
1,745
字号
		reason = (int *) ((void *)gph + sizeof(*gph));		sprintf(buf, "%d,2", *reason);		atcmd_len = 1 + strlen("AT+CCFC=") + strlen(buf);		cmd = atcmd_fill("AT+CCFC=", atcmd_len,				 &voicecall_fwd_stat_cb, gu, gph->id, NULL);		if (!cmd)			return -ENOMEM;		sprintf(cmd->buf, "AT+CCFC=%s", buf);		break;	case GSMD_VOICECALL_FWD_REG:		if(len < sizeof(*gph) + sizeof(int))			return -EINVAL;				gcfr = (struct gsmd_call_fwd_reg *) ((void *)gph + sizeof(*gph));		sprintf(buf, "%d,3,\"%s\"", gcfr->reason, gcfr->addr.number);		atcmd_len = 1 + strlen("AT+CCFC=") + strlen(buf);		cmd = atcmd_fill("AT+CCFC=", atcmd_len,				 &usock_cmd_cb, gu, gph->id, NULL);		if (!cmd)			return -ENOMEM;		sprintf(cmd->buf, "AT+CCFC=%s", buf);		break;	case GSMD_VOICECALL_FWD_ERAS:		if(len < sizeof(*gph) + sizeof(int))			return -EINVAL;				reason = (int *) ((void *)gph + sizeof(*gph));		sprintf(buf, "%d,4", *reason);		atcmd_len = 1 + strlen("AT+CCFC=") + strlen(buf);		cmd = atcmd_fill("AT+CCFC=", atcmd_len,				 &usock_cmd_cb, gu, gph->id, NULL);		if (!cmd)			return -ENOMEM;		sprintf(cmd->buf, "AT+CCFC=%s", buf);		break;	default:		return -EINVAL;	}	if (cmd)		return atcmd_submit(gu->gsmd, cmd);	else		return -ENOMEM;}static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	gsmd_log(GSMD_DEBUG, "null cmd cb\n");	return 0;}/* PIN command callback. Gets called for response to AT+CPIN cmcd */static int pin_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	int ret = cmd->ret;	/* Pass a GSM07.07 CME code directly, don't issue a new PIN	 * request because the client waits for a response to her	 * PIN submission rather than an event.  */	return gsmd_ucmd_submit(gu, GSMD_MSG_PIN, GSMD_PIN_INPUT,			cmd->id, sizeof(ret), &ret);}static const char *pin_type_names[__NUM_GSMD_PIN] = {	[GSMD_PIN_READY]	= "READY",	[GSMD_PIN_SIM_PIN]	= "SIM PIN",	[GSMD_PIN_SIM_PUK]	= "SIM PUK",	[GSMD_PIN_PH_SIM_PIN]	= "Phone-to-SIM PIN",	[GSMD_PIN_PH_FSIM_PIN]	= "Phone-to-very-first SIM PIN",	[GSMD_PIN_PH_FSIM_PUK]	= "Phone-to-very-first SIM PUK",	[GSMD_PIN_SIM_PIN2]	= "SIM PIN2",	[GSMD_PIN_SIM_PUK2]	= "SIM PUK2",	[GSMD_PIN_PH_NET_PIN]	= "Network personalization PIN",	[GSMD_PIN_PH_NET_PUK]	= "Network personalizaiton PUK",	[GSMD_PIN_PH_NETSUB_PIN]= "Network subset personalisation PIN",	[GSMD_PIN_PH_NETSUB_PUK]= "Network subset personalisation PUK",	[GSMD_PIN_PH_SP_PIN]	= "Service provider personalisation PIN",	[GSMD_PIN_PH_SP_PUK]	= "Service provider personalisation PUK",	[GSMD_PIN_PH_CORP_PIN]	= "Corporate personalisation PIN",	[GSMD_PIN_PH_CORP_PUK]	= "Corporate personalisation PUK",};static int get_cpin_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	enum gsmd_pin_type type;	if (!strncmp(resp, "+CPIN: ", 7)) {		unsigned int i;		resp += 7;		for (i = 0; i < __NUM_GSMD_PIN; i++) {			if(!strcmp(resp,pin_type_names[i]))				type = i;		}	}	return gsmd_ucmd_submit(ctx, GSMD_MSG_PIN, GSMD_PIN_GET_STATUS,			cmd->id, sizeof(type), &type);}static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 			 int len){	struct gsmd_pin *gp = (struct gsmd_pin *) ((void *)gph + sizeof(*gph));	struct gsmd_atcmd *cmd;	switch (gph->msg_subtype) {	case GSMD_PIN_INPUT:		if (gph->len < sizeof(*gp) || len < sizeof(*gp)+sizeof(*gph))			return -EINVAL;		gsmd_log(GSMD_DEBUG, "pin type=%u, pin='%s', newpin='%s'\n",			 gp->type, gp->pin, gp->newpin);		cmd = atcmd_fill("AT+CPIN=\"", 9+GSMD_PIN_MAXLEN+3+GSMD_PIN_MAXLEN+2,			 &pin_cmd_cb, gu, 0, NULL);		if (!cmd)			return -ENOMEM;		strlcat(cmd->buf, gp->pin, cmd->buflen);		switch (gp->type) {			case GSMD_PIN_SIM_PUK:			case GSMD_PIN_SIM_PUK2:				strlcat(cmd->buf, "\",\"", cmd->buflen);				strlcat(cmd->buf, gp->newpin, cmd->buflen);			break;		default:			break;		}		strlcat(cmd->buf, "\"", cmd->buflen);		break;	case GSMD_PIN_GET_STATUS:		cmd = atcmd_fill("AT+CPIN?", 8 + 1, &get_cpin_cb, gu, 0, NULL);		break;	default:		gsmd_log(GSMD_ERROR, "unknown pin type %u\n",			 gph->msg_subtype);		return -EINVAL;	}	return atcmd_submit(gu->gsmd, cmd);}static int phone_powerup_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	int ret = cmd->ret;	/* We need to verify if there is some error */	switch (ret) {	case 0:		gsmd_log(GSMD_DEBUG, "Radio powered-up\n");		gu->gsmd->dev_state.on = 1;		break;	default:		/* something went wrong */		gsmd_log(GSMD_DEBUG, "Radio power-up failed\n");		break;	}	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_POWERUP,			cmd->id, sizeof(ret), &ret);}static int phone_powerdown_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	int ret = cmd->ret;	return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_POWERDOWN,			cmd->id, sizeof(ret), &ret);}static int phone_power_status_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	DEBUGP("resp: %s\n", resp);	if (!strncmp(resp, "+CFUN: ", 7))		resp += 7;	return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_POWER_STATUS,			cmd->id, strlen(resp) + 1, resp);}static int phone_get_manuf_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);	if (!strncmp(resp, "+CGMI: ", 7))		resp += 7;	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_MANUF,			cmd->id, strlen(resp) + 1, resp);}static int phone_get_model_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);	if (!strncmp(resp, "+CGMM: ", 7))		resp += 7;	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_MODEL,			cmd->id, strlen(resp) + 1, resp);}static int phone_get_revision_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);	if (!strncmp(resp, "+CGMR: ", 7))		resp += 7;	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_REVISION,			cmd->id, strlen(resp) + 1, resp);}static int phone_get_serial_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);	if (!strncmp(resp, "+CGSN: ", 7))		resp += 7;	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_SERIAL,			cmd->id, strlen(resp) + 1, resp);}static int phone_get_battery_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	struct gsmd_battery_charge gbs;	struct gsm_extrsp *er;	DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);	er = extrsp_parse(gsmd_tallocs, resp);	if(!er)		return -ENOMEM;	/* +CBC: 0,0 */	if((er->num_tokens == 2) &&			er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC &&			er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC ) {				gbs.bcs = er->tokens[0].u.numeric;				gbs.bcl = er->tokens[1].u.numeric;	}	talloc_free(er);	return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_BATTERY,		cmd -> id, sizeof(gbs), &gbs);}static int phone_vibrator_enable_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	int ret = cmd->ret;	switch(ret) {	case 0:		gsmd_log(GSMD_DEBUG, "Vibrator enabled\n");		gu->gsmd->dev_state.vibrator = 1;		break;	default:		gsmd_log(GSMD_DEBUG, "AT+CVIB=1 operation failed\n");		break;	}		return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_VIB_ENABLE,				cmd->id, sizeof(ret), &ret);}static int phone_vibrator_disable_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	int ret = cmd->ret;	return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_VIB_DISABLE,				cmd->id, sizeof(ret), &ret);}	static int usock_rcv_phone(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 			   int len){	struct gsmd_atcmd *cmd;	switch (gph->msg_subtype) {	case GSMD_PHONE_POWERUP:		cmd = atcmd_fill("AT+CFUN=1", 9+1,				&phone_powerup_cb, gu, 0, NULL);		break;	case GSMD_PHONE_POWERDOWN:		cmd = atcmd_fill("AT+CFUN=0", 9+1,				&phone_powerdown_cb, gu, 0, NULL);		gu->gsmd->dev_state.on = 0;		break;	case GSMD_PHONE_POWER_STATUS:		cmd = atcmd_fill("AT+CFUN?", 8+1,				&phone_power_status_cb, gu, 0, NULL);		break;	case GSMD_PHONE_GET_IMSI:		return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_IMSI,			0, strlen(gu->gsmd->imsi) + 1, gu->gsmd->imsi);		break;	case GSMD_PHONE_GET_MANUF:		cmd = atcmd_fill("AT+CGMI", 7+1,				&phone_get_manuf_cb, gu, 0, NULL);		break;	case GSMD_PHONE_GET_MODEL:		cmd = atcmd_fill("AT+CGMM", 7+1,				&phone_get_model_cb, gu, 0, NULL);		break;	case GSMD_PHONE_GET_REVISION:		cmd = atcmd_fill("AT+CGMR", 7+1,				&phone_get_revision_cb, gu, 0, NULL);		break;	case GSMD_PHONE_GET_SERIAL:		cmd = atcmd_fill("AT+CGSN", 7+1,				&phone_get_serial_cb, gu, 0, NULL);		break;	case GSMD_PHONE_GET_BATTERY:		cmd = atcmd_fill("AT+CBC", 6+1, &phone_get_battery_cb, gu, 0, NULL);		break;	case GSMD_PHONE_VIB_ENABLE:		cmd = atcmd_fill("AT+CVIB=1", 9+1, &phone_vibrator_enable_cb, gu, 0, NULL);		break;	case GSMD_PHONE_VIB_DISABLE:		cmd = atcmd_fill("AT+CVIB=0", 9+1, &phone_vibrator_disable_cb, gu, 0, NULL);		gu->gsmd->dev_state.vibrator = 0;		break;	default:		return -EINVAL;	}	if (!cmd)		return -ENOMEM;	return atcmd_submit(gu->gsmd, cmd);}static int usock_rcv_modem(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 			   int len){	struct gsmd *g = gu->gsmd;	if (g->machinepl->power) {		g->machinepl->power(g, gph->msg_subtype);	}	return 0; }static int network_query_reg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	struct gsm_extrsp *er;	enum gsmd_netreg_state state;	DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);	if (strncmp(resp, "+CREG: ", 7))		return -EINVAL;	er = extrsp_parse(gsmd_tallocs, resp);	if(!er)		return -ENOMEM;	//extrsp_dump(er);	/* +CREG: <n>,<stat>[,<lac>,<ci>] */	if((er->num_tokens == 4 || er->num_tokens == 2 ) &&			er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC &&			er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC ) {				state = er->tokens[1].u.numeric;	}	talloc_free(er);	return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_QUERY_REG,		cmd->id, sizeof(state), &state);}static int network_vmail_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){	struct gsmd_user *gu = ctx;	struct gsmd_voicemail vmail;	struct gsm_extrsp *er;	int rc;	int ret = cmd->ret;	DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);	if (cmd->buf[7] == '=') {		/* response to set command */		rc = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, 				GSMD_NETWORK_VMAIL_SET,cmd->id, sizeof(ret), &ret);	} else {		/* response to get command */		if (strncmp(resp, "+CSVM: ", 7))			return -EINVAL;		resp += 7;		er = extrsp_parse(gsmd_tallocs, resp);		if(!er)			return -ENOMEM;		if(er->num_tokens == 3 &&			er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC &&			er->tokens[1].type == GSMD_ECMD_RTT_STRING &&			er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC) {				vmail.enable = er->tokens[0].u.numeric;				strlcpy(vmail.addr.number, er->tokens[1].u.string, GSMD_ADDR_MAXLEN+1);				vmail.addr.type = er->tokens[2].u.numeric;		}		rc = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_VMAIL_GET,			cmd->id, sizeof(vmail), &vmail);		talloc_free(er);	}	return rc;}int gsmd_ucmd_submit(struct gsmd_user *gu, u_int8_t msg_type,		u_int8_t msg_subtype, u_int16_t id, int len, const void *data){	struct gsmd_ucmd *ucmd = ucmd_alloc(len);	if (!ucmd)		return -ENOMEM;	ucmd->hdr.version = GSMD_PROTO_VERSION;	ucmd->hdr.msg_type = msg_type;	ucmd->hdr.msg_subtype = msg_subtype;	ucmd->hdr.len = len;	ucmd->hdr.id = id;	memcpy(ucmd->buf, data, len);	usock_cmd_enqueue(ucmd, gu);	return 0;}static int network_sigq_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){

⌨️ 快捷键说明

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