コード例 #1
0
ファイル: at-emulator.c プロジェクト: ihipop/I-GNOKII
/* Parser for DIR sub mode of SMS interactive mode. */
void	gn_atem_dir_parse(char *buff)
{
	switch (toupper(*buff)) {
		case 'P':
			SMSNumber--;
			gn_atem_sms_handle();
			return;
		case 'N':
			SMSNumber++;
			gn_atem_sms_handle();
			return;
		case 'D':
			data.sms->memory_type = SMSType;
			data.sms->number = SMSNumber;
			if (gn_sm_functions(GN_OP_DeleteSMS, &data, sm) == GN_ERR_NONE) {
				gn_atem_modem_result(MR_OK);
			} else {
				gn_atem_modem_result(MR_ERROR);
			}
			return;
		case 'Q':
			Parser= gn_atem_sms_parse;
			gn_atem_modem_result(MR_OK);
			return;
	}
	gn_atem_modem_result(MR_ERROR);
}
コード例 #2
0
ファイル: at-emulator.c プロジェクト: xianjimli/misc
/* Parser for entering message content (+CMGS) */
void	gn_atem_sms_parseText(char *buff)
{
	static int index = 0;
	int i, length;
	char buffer[MAX_LINE_LENGTH];
	gn_error error;

	length = strlen(buff);

	sms.user_data[0].type = GN_SMS_DATA_Text;

	for (i = 0; i < length; i++) {

		if (buff[i] == ModemRegisters[REG_CTRLZ]) {
			/* Exit SMS text mode with sending */
			sms.user_data[0].u.text[index] = 0;
			sms.user_data[0].length = index;
			index = 0;
			Parser = gn_atem_at_parse;
			dprintf("Sending SMS to %s (text: %s)\n", data.sms->remote.number, data.sms->user_data[0].u.text);

			/* FIXME: set more SMS fields before sending */
			error = gn_sms_send(&data, sm);

			if (error == GN_ERR_NONE) {
				gsprintf(buffer, MAX_LINE_LENGTH, "+CMGS: %d\r\n", data.sms->number);
				gn_atem_string_out(buffer);
				gn_atem_modem_result(MR_OK);
			} else {
				gn_atem_string_out(gn_atem_cme(0));
				gn_atem_string_out("\r\n");
			}
			return;
		} else if (buff[i] == ModemRegisters[REG_ESCAPE]) {
			/* Exit SMS text mode without sending */
			sms.user_data[0].u.text[index] = 0;
			sms.user_data[0].length = index;
			index = 0;
			Parser = gn_atem_at_parse;
			gn_atem_modem_result(MR_OK);
			return;
		} else {
			/* Appent next char to message text */
			sms.user_data[0].u.text[index++] = buff[i];
		}
	}

	/* reached the end of line so insert \n and wait for more */
	sms.user_data[0].u.text[index++] = '\n';
	gn_atem_string_out("\r\n> ");
}
コード例 #3
0
ファイル: at-emulator.c プロジェクト: ihipop/I-GNOKII
/* This gets called to output caller id info of incoming call */
void gn_atem_cid_out(gn_call_info *CallInfo)
{
	struct tm *now;
	time_t nowh;
	char buf[14]; /* 7 for "DATE = " + 4 digits + \n + \r + \0 */

	nowh = time(NULL);
	now = localtime(&nowh);

	switch (CallerIDMode) {
	case 0:	/* no output */
		break;
	case 1: /* formatted CID */
		snprintf(buf, sizeof(buf), "DATE = %02d%02d\r\n", now->tm_mon + 1, now->tm_mday);
		gn_atem_string_out(buf);

		snprintf(buf, sizeof(buf), "TIME = %02d%02d\r\n", now->tm_hour, now->tm_min);
		gn_atem_string_out(buf);

		/* TO DO: handle P and O numbers */
		gn_atem_string_out("NMBR = ");
		gn_atem_string_out(1 + CallInfo->number); /* skip leading "+" */
		gn_atem_string_out("\r\nNAME = ");
		gn_atem_string_out(CallInfo->name);
		gn_atem_string_out("\r\n");

		/* FIX ME: do a real emulation of rings after the first one (at a lower level than this) */
		gn_atem_modem_result(MR_RING);

		break;

	}
}
コード例 #4
0
ファイル: at-emulator.c プロジェクト: xianjimli/misc
/* This gets called to indicate an incoming call */
void gn_atem_call_passup(gn_call_status CallStatus, gn_call_info *CallInfo, struct gn_statemachine *state)
{
	dprintf("gn_atem_call_passup called with %d\n", CallStatus);

	switch (CallStatus) {
	case GN_CALL_Incoming:
		IncomingCallNo = CallInfo->call_id;
		gn_atem_modem_result(MR_RING);
		ModemRegisters[REG_RINGCNT]++;
		gn_atem_cid_out(CallInfo);
		if (ModemRegisters[REG_RINGATA] != 0) gn_atem_answer_phone();
		break;
	case GN_CALL_LocalHangup:
	case GN_CALL_RemoteHangup:
		if (IncomingCallNo > 0) {
			gn_atem_cpi(GSMD_CALLPROG_DISCONNECT,
					GSMD_CALL_DIR_MT, 0);
			gn_atem_cpi(GSMD_CALLPROG_RELEASE,
					GSMD_CALL_DIR_MT, 0);
		}
		IncomingCallNo = -1;
		break;
	default:
		break;
	}
}
コード例 #5
0
ファイル: at-emulator.c プロジェクト: ihipop/I-GNOKII
/* Parser for SMS interactive mode */
void	gn_atem_sms_parse(char *buff)
{
	if (!strcasecmp(buff, "HELP")) {
		gn_atem_string_out(_("\r\nThe following commands work...\r\n"));
		gn_atem_string_out("DIR\r\n");
		gn_atem_string_out("EXIT\r\n");
		gn_atem_string_out("HELP\r\n");
		return;
	}

	if (!strcasecmp(buff, "DIR")) {
		SMSNumber = 1;
		gn_atem_sms_handle();
		Parser = gn_atem_dir_parse;
		return;
	}
	if (!strcasecmp(buff, "EXIT")) {
		Parser = gn_atem_at_parse;
		gn_atem_modem_result(MR_OK);
		return;
	}
	gn_atem_modem_result(MR_ERROR);
}
コード例 #6
0
ファイル: at-emulator.c プロジェクト: ihipop/I-GNOKII
/* This gets called to indicate an incoming call */
void gn_atem_call_passup(gn_call_status CallStatus, gn_call_info *CallInfo, struct gn_statemachine *state, void *callback_data)
{
	dprintf("gn_atem_call_passup called with %d\n", CallStatus);

	switch (CallStatus) {
	case GN_CALL_Incoming:
		gn_atem_modem_result(MR_RING);
		IncomingCallNo = CallInfo->call_id;
		ModemRegisters[REG_RINGCNT]++;
		gn_atem_cid_out(CallInfo);
		if (ModemRegisters[REG_RINGATA] != 0) gn_atem_answer_phone();
		break;
	case GN_CALL_LocalHangup:
	case GN_CALL_RemoteHangup:
		IncomingCallNo = -1;
		break;
	default:
		break;
	}
}
コード例 #7
0
ファイル: at-emulator.c プロジェクト: ihipop/I-GNOKII
/* Parser for standard AT commands.  cmd_buffer must be null terminated. */
void	gn_atem_at_parse(char *cmd_buffer)
{
	char *buf;
	int regno, val;
	char str[256];

	if (!cmd_buffer[0]) return;

	if (strncasecmp (cmd_buffer, "AT", 2) != 0) {
		gn_atem_modem_result(MR_ERROR);
		return;
	}

	for (buf = &cmd_buffer[2]; *buf;) {
		switch (toupper(*buf)) {

		case 'Z':
			/* Reset modem */
			buf++;
			switch (gn_atem_num_get(&buf)) {
			case -1:
			case 0:	/* reset and load stored profile 0 */
			case 1:	/* reset and load stored profile 1 */
				gn_atem_hangup_phone();
				gn_atem_registers_init();
				break;
			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		case 'A':
		        /* Answer call */
			buf++;
			gn_atem_answer_phone();
			return;
			break;

		case 'D':
			/* Dial Data :-) */
			/* FIXME - should parse this better */
			/* For now we'll also initialise the datapump + rlp code again */
			dp_Initialise(PtyRDFD, PtyWRFD);
			buf++;
			if (toupper(*buf) == 'T' || toupper(*buf) == 'P') buf++;
			while (*buf == ' ') buf++;
			data.call_notification = dp_CallPassup;
			gn_sm_functions(GN_OP_SetCallNotification, &data, sm);
			snprintf(data.call_info->number, sizeof(data.call_info->number), "%s", buf);
			if (ModemRegisters[S35] == 0)
				data.call_info->type = GN_CALL_DigitalData;
			else
				data.call_info->type = GN_CALL_NonDigitalData;
			data.call_info->send_number = GN_CALL_Default;
			CommandMode = false;
			if (gn_sm_functions(GN_OP_MakeCall, &data, sm) != GN_ERR_NONE) {
				CommandMode = true;
				dp_CallPassup(GN_CALL_RemoteHangup, NULL, NULL, NULL);
			} else {
				IncomingCallNo = data.call_info->call_id;
				gn_sm_loop(10, sm);
			}
			return;
			break;

		case 'H':
			/* Hang Up */
			buf++;
			switch (gn_atem_num_get(&buf)) {
			case -1:
			case 0:	/* hook off the phone */
				gn_atem_hangup_phone();
				break;
			case 1:	/* hook on the phone */
				break;
			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		case 'S':
			/* Change registers */
			buf++;
			regno = gn_atem_num_get(&buf);
			if (regno < 0 || regno >= MAX_MODEM_REGISTERS) {
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			if (*buf == '=') {
				buf++;
				val = gn_atem_num_get(&buf);
				if (val < 0 || val > 255) {
					gn_atem_modem_result(MR_ERROR);
					return;
				}
				ModemRegisters[regno] = val;
			} else if (*buf == '?') {
				buf++;
				snprintf(str, sizeof(str), "%d\r\n", ModemRegisters[regno]);
				gn_atem_string_out(str);
			} else {
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		case 'E':
		        /* E - Turn Echo on/off */
			buf++;
			switch (gn_atem_num_get(&buf)) {
			case -1:
			case 0:
				ModemRegisters[REG_ECHO] &= ~BIT_ECHO;
				break;
			case 1:
				ModemRegisters[REG_ECHO] |= BIT_ECHO;
				break;
			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		case 'Q':
		        /* Q - Turn Quiet on/off */
			buf++;
			switch (gn_atem_num_get(&buf)) {
			case -1:
			case 0:
				ModemRegisters[REG_QUIET] &= ~BIT_QUIET;
				break;
			case 1:
				ModemRegisters[REG_QUIET] |= BIT_QUIET;
				break;
			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		case 'V':
		        /* V - Turn Verbose on/off */
			buf++;
			switch (gn_atem_num_get(&buf)) {
			case -1:
			case 0:
				ModemRegisters[REG_VERBOSE] &= ~BIT_VERBOSE;
				break;
			case 1:
				ModemRegisters[REG_VERBOSE] |= BIT_VERBOSE;
				break;
			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		case 'X':
		        /* X - Set verbosity of the result messages */
			buf++;
			switch (gn_atem_num_get(&buf)) {
			case -1:
			case 0: val = 0x00; break;
			case 1: val = 0x40; break;
			case 2: val = 0x50; break;
			case 3: val = 0x60; break;
			case 4: val = 0x70; break;
			case 5: val = 0x10; break;
			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			ModemRegisters[S22] = (ModemRegisters[S22] & 0x8f) | val;
			break;

		case 'I':
		        /* I - info */
			buf++;
			switch (gn_atem_num_get(&buf)) {
			case -1:
			case 0:	/* terminal id */
				snprintf(str, sizeof(str), "%d\r\n", ModemRegisters[39]);
				gn_atem_string_out(str);
				break;
			case 1:	/* serial number (IMEI) */
				snprintf(str, sizeof(str), "%s\r\n", imei);
				gn_atem_string_out(str);
				break;
			case 2: /* phone revision */
				snprintf(str, sizeof(str), "%s\r\n", revision);
				gn_atem_string_out(str);
				break;
			case 3: /* modem revision */
				gn_atem_string_out("gnokiid " VERSION "\r\n");
				break;
			case 4: /* OEM string */
				snprintf(str, sizeof(str), "%s %s\r\n", manufacturer, model);
				gn_atem_string_out(str);
				break;
			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		  /* Handle AT* commands (Nokia proprietary I think) */
		case '*':
			buf++;
			if (!strcasecmp(buf, "NOKIATEST")) {
				gn_atem_modem_result(MR_OK); /* FIXME? */
				return;
			} else {
				if (!strcasecmp(buf, "C")) {
					gn_atem_modem_result(MR_OK);
					Parser = gn_atem_sms_parse;
					return;
				}
			}
			break;

		/* + is the precursor to another set of commands */
		case '+':
			buf++;
			switch (toupper(*buf)) {
			case 'C':
				buf++;
				/* Returns true if error occured */
				if (gn_atem_command_plusc(&buf) == true) {
					gn_atem_modem_result(MR_ERROR);
					return;
				}
				break;

			case 'G':
				buf++;
				/* Returns true if error occured */
				if (gn_atem_command_plusg(&buf) == true) {
					gn_atem_modem_result(MR_ERROR);
					return;
				}
				break;

			default:
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		/* # is the precursor to another set of commands */
		case '#':
			buf++;
			/* Returns true if error occured */
			if (gn_atem_command_diesis(&buf) == true) {
				gn_atem_modem_result(MR_ERROR);
				return;
			}
			break;

		default:
			gn_atem_modem_result(MR_ERROR);
			return;
		}
	}

	gn_atem_modem_result(MR_OK);
}