Example #1
0
static const char* parse_cmgr_pdu(char** str, attribute_unused size_t len, char* oa, size_t oa_len, str_encoding_t* oa_enc, char** msg, str_encoding_t* msg_enc)
{
	/*
	 * parse cmgr info in the following PDU format
	 * +CMGR: message_status,[address_text],TPDU_length<CR><LF>
	 * SMSC_number_and_TPDU<CR><LF><CR><LF>
	 * OK<CR><LF>
	 *
	 *	sample
	 * +CMGR: 1,,31
	 * 07911234567890F3040B911234556780F20008012150220040210C041F04400438043204350442<CR><LF><CR><LF>
	 * OK<CR><LF>
	 */

	char delimiters[] = ",,\n";
	char * marks[STRLEN(delimiters)];
	char * end;
	size_t tpdu_length;

	if(mark_line(*str, delimiters, marks) == ITEMS_OF(marks))
	{
		tpdu_length = strtol(marks[1] + 1, &end, 10);
		if(tpdu_length <= 0 || end[0] != '\r')
			return "Invalid TPDU length in CMGR PDU status line";
		*str = marks[2] + 1;
		return pdu_parse(str, tpdu_length, oa, oa_len, oa_enc, msg, msg_enc);
	}

	return "Can't parse +CMGR response";
}
/* array in order of values RECODE_*  */
static const coder recoders[STR_ENCODING_UNKNOWN][2] =
{
	[STR_ENCODING_7BIT_HEX_PAD_0] = { hexstr_7bit_to_char_pad_0, char_to_hexstr_7bit_pad_0 },
	[STR_ENCODING_8BIT_HEX] = { hexstr_to_8bitchars, chars8bit_to_hexstr },
	[STR_ENCODING_UCS2_HEX] = { hexstr_ucs2_to_utf8, utf8_to_hexstr_ucs2 },
	[STR_ENCODING_7BIT] = { just_copy, just_copy },
	[STR_ENCODING_7BIT_HEX_PAD_1] = { hexstr_7bit_to_char_pad_1, char_to_hexstr_7bit_pad_1 },
	[STR_ENCODING_7BIT_HEX_PAD_2] = { hexstr_7bit_to_char_pad_2, char_to_hexstr_7bit_pad_2 },
	[STR_ENCODING_7BIT_HEX_PAD_3] = { hexstr_7bit_to_char_pad_3, char_to_hexstr_7bit_pad_3 },
	[STR_ENCODING_7BIT_HEX_PAD_4] = { hexstr_7bit_to_char_pad_4, char_to_hexstr_7bit_pad_4 },
	[STR_ENCODING_7BIT_HEX_PAD_5] = { hexstr_7bit_to_char_pad_5, char_to_hexstr_7bit_pad_5 },
	[STR_ENCODING_7BIT_HEX_PAD_6] = { hexstr_7bit_to_char_pad_6, char_to_hexstr_7bit_pad_6 },
};

#/* */
EXPORT_DEF ssize_t str_recode(recode_direction_t dir, str_encoding_t encoding, const char* in, size_t in_length, char* out, size_t out_size)
{
	unsigned idx = encoding;
	if((dir == RECODE_DECODE || dir == RECODE_ENCODE) && idx < ITEMS_OF(recoders))
		return (recoders[idx][dir])(in, in_length, out, out_size);
	return -EINVAL;
}
Example #3
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "at_parse.h"			/* at_parse_*() */
#include "mutils.h"			/* ITEMS_OF() */


int ok = 0;
int faults = 0;

int test_strcmp(const char *pa, const char *pb)
{
	int retval;

	if (pa == NULL)
		pa = "";
	if (pb == NULL)
		pb = "";
	retval = strcmp(pa,pb);

	if (retval != 0) {
		int x = 0;
		while (pa[x] == pb[x] && pa[x] != 0) {
			x++;
		}
		printf("String '%s' and '%s' differs at "
		    "offset %d '%c' != '%c'\n", pa, pb, x, pa[x], pb[x]);
	}
	return (retval);
}

#/* */
void test_parse_cnum()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+CNUM: \"*Subscriber Number\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"Subscriber Number\",\"\",145", "" },
		{ "+CNUM: \"Subscriber Number\",,145", "" },
		{ "+CNUM: \"\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: ,\"\",145", "" },
		{ "+CNUM: ,,145", "" },
		{ "+CNUM: \"\",+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"\",+79139131234,145", "+79139131234" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cnum", input);
		res = at_parse_cnum(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cops()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+COPS: 0,0,\"TELE2\",0", "TELE2" },
		{ "+COPS: 0,0,\"TELE2,0", "TELE2" },
		{ "+COPS: 0,0,TELE2,0", "TELE2" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cops", input);
		res = at_parse_cops(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}
Example #4
0
/*!
 * \brief Enque a answer commands
 * \param cpvt -- cpvt structure
 * \return 0 on success
 */
EXPORT_DEF int at_enque_answer(struct cpvt* cpvt)
{
	at_queue_cmd_t cmds[] = {
		ATQ_CMD_DECLARE_DYN(CMD_AT_A),
		ATQ_CMD_DECLARE_ST(CMD_AT_DDSETEX, cmd_ddsetex2),
		};
	int err;
	int count = ITEMS_OF(cmds);
	const char * cmd1;

	if(cpvt->state == CALL_STATE_INCOMING)
	{
/* FIXME: channel number? */
		cmd1 = "ATA\r";
	}
	else if(cpvt->state == CALL_STATE_WAITING)
	{
		cmds[0].cmd = CMD_AT_CHLD_2x;
		cmd1 = "AT+CHLD=2%d\r";
/* no need CMD_AT_DDSETEX in this case? */
		count--;
	}
	else
	{
		ast_log (LOG_ERROR, "[%s] Request answer for call idx %d with state '%s'\n", PVT_ID(cpvt->pvt), cpvt->call_idx, call_state2str(cpvt->state));
		return -1;
	}

	err = at_fill_generic_cmd(&cmds[0], cmd1, cpvt->call_idx);
	if(err == 0)
		err = at_queue_insert(cpvt, cmds, count, 1);
	return err;
}
Example #5
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "at_parse.h"			/* at_parse_*() */
#include "mutils.h"			/* ITEMS_OF() */


int ok = 0;
int faults = 0;

int test_strcmp(const char *pa, const char *pb)
{
	int retval;

	if (pa == NULL)
		pa = "";
	if (pb == NULL)
		pb = "";
	retval = strcmp(pa,pb);

	if (retval != 0) {
		int x = 0;
		while (pa[x] == pb[x] && pa[x] != 0) {
			x++;
		}
		printf("String '%s' and '%s' differs at "
		    "offset %d '%c' != '%c'\n", pa, pb, x, pa[x], pb[x]);
	}
	return (retval);
}

#/* */
void test_parse_cnum()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+CNUM: \"*Subscriber Number\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"Subscriber Number\",\"\",145", "" },
		{ "+CNUM: \"Subscriber Number\",,145", "" },
		{ "+CNUM: \"\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: ,\"\",145", "" },
		{ "+CNUM: ,,145", "" },
		{ "+CNUM: \"\",+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"\",+79139131234,145", "+79139131234" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cnum", input);
		res = at_parse_cnum(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cops()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+COPS: 0,0,\"TELE2\",0", "TELE2" },
		{ "+COPS: 0,0,\"TELE2,0", "TELE2" },
		{ "+COPS: 0,0,TELE2,0", "TELE2" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cops", input);
		res = at_parse_cops(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_creg()
{
	struct result {
		int	res;
		int	gsm_reg;
		int	gsm_reg_status;
		char 	* lac;
		char	* ci;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CREG: 2,1,9110,7E6", { 0, 1, 1, "9110", "7E6"} },
		{ "+CREG: 2,1,XXXX,AAAA", { 0, 1, 1, "XXXX", "AAAA"} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_creg", input);
		result.res = at_parse_creg(input, strlen(input), &result.gsm_reg, &result.gsm_reg_status, &result.lac, &result.ci);
		if(result.res == cases[idx].result.res
			&&
		   result.gsm_reg == cases[idx].result.gsm_reg
			&&
		   result.gsm_reg_status == cases[idx].result.gsm_reg_status
			&&
		   test_strcmp(result.lac, cases[idx].result.lac) == 0
			&&
		   test_strcmp(result.ci, cases[idx].result.ci) == 0
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,%d,\"%s\",\"%s\")\t%s\n", result.res, result.gsm_reg, result.gsm_reg_status, result.lac, result.ci, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cmti()
{
	static const struct test_case {
		const char	* input;
		int		result;
	} cases[] = {
		{ "+CMTI: \"ME\",41", 41 },
		{ "+CMTI: 0,111", 111 },
		{ "+CMTI: ", -1 },
	};
	unsigned idx = 0;
	char * input;
	int result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmti", input);
		result = at_parse_cmti(input);
		if(result == cases[idx].result) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d\t%s\n", result, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}
Example #6
0
EXPORT_DEF int at_enque_set_ccwa (struct cpvt* cpvt, attribute_unused const char * unused1, attribute_unused const char * unused2, unsigned call_waiting)
{
	static const char cmd_ccwa_get[] = "AT+CCWA=1,2,1\r";
	static const char cmd_ccwa_set[] = "AT+CCWA=%d,%d,%d\r";
	int err;
	call_waiting_t value;
	at_queue_cmd_t cmds[] = {
		/* 5 seconds timeout */
		ATQ_CMD_DECLARE_DYNIT(CMD_AT_CCWA_SET, ATQ_CMD_TIMEOUT_15S, 0),				/* Set Call-Waiting On/Off */
		ATQ_CMD_DECLARE_STIT(CMD_AT_CCWA_STATUS, cmd_ccwa_get, ATQ_CMD_TIMEOUT_15S, 0),		/* Query CCWA Status for Voice Call  */

	};
	at_queue_cmd_t * pcmd = cmds;
	unsigned count = ITEMS_OF(cmds);

	if(call_waiting == CALL_WAITING_DISALLOWED || call_waiting == CALL_WAITING_ALLOWED)
	{
		value = call_waiting;
		err = call_waiting == CALL_WAITING_ALLOWED ? 1 : 0;
		err = at_fill_generic_cmd(&cmds[0], cmd_ccwa_set, err, err, CCWA_CLASS_VOICE);
		if(err)
		    return err;
	}
	else
	{
		value = CALL_WAITING_AUTO;
		pcmd++;
		count--;
	}
	CONF_SHARED(cpvt->pvt, callwaiting) = value;

	return at_queue_insert(cpvt, pcmd, count, 0);
}
Example #7
0
EXPORT_DEF char* at_parse_cops (char* str)
{
	/*
	 * parse COPS response in the following format:
	 * +COPS: <mode>[,<format>,<oper>,<?>]
	 *
	 * example 
	 *  +COPS: 0,0,"TELE2",0
	 */

	char delimiters[] = ":,,,";
	char * marks[STRLEN(delimiters)];

	/* parse URC only here */
	if(mark_line(str, delimiters, marks) == ITEMS_OF(marks))
	{
		marks[2]++;
		if(marks[2][0] == '"')
			marks[2]++;
		if(marks[3][-1] == '"')
			marks[3]--;
		marks[3][0] = 0;
		return marks[2];
	}

	return NULL;
}
Example #8
0
/*!
 * \brief Enque ping command
 * \param pvt -- pvt structure
 * \return 0 on success
 */
EXPORT_DEF int at_enque_ping (struct cpvt * cpvt)
{
	static const at_queue_cmd_t cmds[] = {
		ATQ_CMD_DECLARE_STIT(CMD_AT, cmd_at, ATQ_CMD_TIMEOUT_1S, 0),		/* 1 second timeout */
		};

	return at_queue_insert_const(cpvt, cmds, ITEMS_OF(cmds), 1);
}
Example #9
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "at_parse.h"			/* at_parse_*() */
#include "mutils.h"			/* ITEMS_OF() */


int ok = 0;
int faults = 0;

int test_strcmp(const char *pa, const char *pb)
{
	int retval;

	if (pa == NULL)
		pa = "";
	if (pb == NULL)
		pb = "";
	retval = strcmp(pa,pb);

	if (retval != 0) {
		int x = 0;
		while (pa[x] == pb[x] && pa[x] != 0) {
			x++;
		}
		printf("String '%s' and '%s' differs at "
		    "offset %d '%c' != '%c'\n", pa, pb, x, pa[x], pb[x]);
	}
	return (retval);
}

#/* */
void test_parse_cnum()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+CNUM: \"*Subscriber Number\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"Subscriber Number\",\"\",145", "" },
		{ "+CNUM: \"Subscriber Number\",,145", "" },
		{ "+CNUM: \"\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: ,\"\",145", "" },
		{ "+CNUM: ,,145", "" },
		{ "+CNUM: \"\",+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"\",+79139131234,145", "+79139131234" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cnum", input);
		res = at_parse_cnum(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cops()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+COPS: 0,0,\"TELE2\",0", "TELE2" },
		{ "+COPS: 0,0,\"TELE2,0", "TELE2" },
		{ "+COPS: 0,0,TELE2,0", "TELE2" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cops", input);
		res = at_parse_cops(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_creg()
{
	struct result {
		int	res;
		int	gsm_reg;
		int	gsm_reg_status;
		char 	* lac;
		char	* ci;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CREG: 2,1,9110,7E6", { 0, 1, 1, "9110", "7E6"} },
		{ "+CREG: 2,1,XXXX,AAAA", { 0, 1, 1, "XXXX", "AAAA"} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_creg", input);
		result.res = at_parse_creg(input, strlen(input), &result.gsm_reg, &result.gsm_reg_status, &result.lac, &result.ci);
		if(result.res == cases[idx].result.res
			&&
		   result.gsm_reg == cases[idx].result.gsm_reg
			&&
		   result.gsm_reg_status == cases[idx].result.gsm_reg_status
			&&
		   test_strcmp(result.lac, cases[idx].result.lac) == 0
			&&
		   test_strcmp(result.ci, cases[idx].result.ci) == 0
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,%d,\"%s\",\"%s\")\t%s\n", result.res, result.gsm_reg, result.gsm_reg_status, result.lac, result.ci, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cmti()
{
	static const struct test_case {
		const char	* input;
		int		result;
	} cases[] = {
		{ "+CMTI: \"ME\",41", 41 },
		{ "+CMTI: 0,111", 111 },
		{ "+CMTI: ", -1 },
	};
	unsigned idx = 0;
	char * input;
	int result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmti", input);
		result = at_parse_cmti(input);
		if(result == cases[idx].result) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d\t%s\n", result, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cmgr()
{
	struct result {
		const char	* res;
		char		* str;
		char 		* oa;
		str_encoding_t	oa_enc;
		char		* msg;
		str_encoding_t	msg_enc;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CMGR: \"REC READ\",\"+79139131234\",,\"10/12/05,22:00:04+12\"\r\n041F04400438043204350442", 
			{
				NULL,
				"\"REC READ\",\"+79139131234",
				"+79139131234",
				STR_ENCODING_7BIT,
				"041F04400438043204350442",
				STR_ENCODING_UNKNOWN
			}
		},
		{ "+CMGR: \"REC READ\",\"002B00370039003500330037003600310032003000350032\",,\"10/12/05,22:00:04+12\"\r\n041F04400438043204350442", 
			{
				NULL, 
				"\"REC READ\",\"002B00370039003500330037003600310032003000350032",
				"002B00370039003500330037003600310032003000350032", 
				STR_ENCODING_UNKNOWN,
				"041F04400438043204350442",
				STR_ENCODING_UNKNOWN
			}
		},
		{ "+CMGR: 0,,106\r\n07911111111100F3040B911111111111F200000121702214952163B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
			{
				NULL,
				"B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
				"+11111111112",
				STR_ENCODING_7BIT,
				"B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
				STR_ENCODING_7BIT_HEX_PAD_0
			} 
		},
		{ "+CMGR: 0,,159\r\n07919740430900F3440B912222222220F20008012180004390218C0500030003010031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
			{
				NULL,
				"0031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
				"+22222222022",
				STR_ENCODING_7BIT,
				"0031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
				STR_ENCODING_UCS2_HEX
			} 
		},
		{ "+CMGR: 0,,158\r\n07916407970970F6400A912222222222000041903021825180A0050003000301A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
			{
				NULL,
				"A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
				"+2222222222",
				STR_ENCODING_7BIT,
				"A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
				STR_ENCODING_7BIT_HEX_PAD_1,
			}
		},
		{ "+CMGR: 0,,55\r\n07912933035011804409D055F3DB5D060000411120712071022A080701030003990202A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
			{
				NULL,
				"A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
				"553",
				STR_ENCODING_7BIT,
				"A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
				STR_ENCODING_7BIT_HEX_PAD_5,
			}
		},
	};

	unsigned idx = 0;
	char * input;
	struct result result;
	char oa[200];
	char buffer_res[256];
	char buffer_dec[256];
	const char * msg;

	result.oa = oa;
	for(; idx < ITEMS_OF(cases); ++idx) {
		result.str = input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmgr", input);
		result.res = at_parse_cmgr(&result.str, strlen(result.str), result.oa, sizeof(oa), &result.oa_enc, &result.msg, &result.msg_enc);
		if( ((result.res == NULL && result.res == cases[idx].result.res) || test_strcmp(result.res, cases[idx].result.res) == 0)
			&&
		   test_strcmp(result.str, cases[idx].result.str) == 0
			&&
		   test_strcmp(result.oa, cases[idx].result.oa) == 0
			&&
		   result.oa_enc == cases[idx].result.oa_enc
			&&
		   test_strcmp(result.msg, cases[idx].result.msg) == 0
			&&
		   result.msg_enc == cases[idx].result.msg_enc
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		memset(buffer_res, 0, sizeof(buffer_res));
		memset(buffer_dec, 0, sizeof(buffer_dec));
		str_recode(RECODE_DECODE, result.msg_enc, result.msg, strlen(result.msg), buffer_res, sizeof(buffer_res));
		str_recode(RECODE_DECODE, cases[idx].result.msg_enc, cases[idx].result.msg, strlen(cases[idx].result.msg), buffer_dec, sizeof(buffer_dec));
		fprintf(stderr, " = '%s' ('%s','%s',%d,'%s',%d,'%s','%s')\t%s\n", result.res, result.str, result.oa, result.oa_enc, result.msg, result.msg_enc, buffer_res, buffer_dec, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cusd()
{
	struct result {
		int	res;
		int	type;
		char 	* cusd;
		int	dcs;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CUSD: 0,\"CF2135487D2E4130572D0682BB1A\",0", { 0, 0, "CF2135487D2E4130572D0682BB1A", 0} },
		{ "+CUSD: 1,\"CF2135487D2E4130572D0682BB1A\",1", { 0, 1, "CF2135487D2E4130572D0682BB1A", 1} },
		{ "+CUSD: 5", { 0, 5, "", -1} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cusd", input);
		result.res = at_parse_cusd(input, &result.type, &result.cusd, &result.dcs);
		if(result.res == cases[idx].result.res
			&&
		   result.type == cases[idx].result.type
			&&
		   result.dcs == cases[idx].result.dcs
			&&
		   test_strcmp(result.cusd, cases[idx].result.cusd) == 0
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,\"%s\",%d)\t%s\n", result.res, result.type, result.cusd, result.dcs, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cpin()
{
}

#/* */
void test_parse_csq()
{
}

#/* */
void test_parse_rssi()
{
}

#/* */
void test_parse_mode()
{
}

#/* */
void test_parse_csca()
{
}

#/* */
void test_parse_clcc()
{
	struct result {
		int		res;

		unsigned	index;
		unsigned	dir;
		unsigned	stat;
		unsigned	mode;
		unsigned	mpty;
		char		* number;
		unsigned	toa;
	};
	static const struct test_case {
		const char	* input;
		struct result	result;
	} cases[] = {
		{ "+CLCC: 1,1,4,0,0,\"\",145", { 0, 1, 1, 4, 0, 0, "", 145} },
		{ "+CLCC: 1,1,4,0,0,\"+79139131234\",145", { 0, 1, 1, 4, 0, 0, "+79139131234", 145} },
		{ "+CLCC: 1,1,4,0,0,\"+7913913ABCA\",145", { 0, 1, 1, 4, 0, 0, "+7913913ABCA", 145} },
		{ "+CLCC: 1,1,4,0,0,\"+7913913ABCA\"", { -1, 0, 0, 0, 0, 0, "", 0} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_clcc", input);
		result.res = at_parse_clcc(input, &result.index, &result.dir, &result.stat, &result.mode, &result.mpty, &result.number, &result.toa);
		if(result.res == cases[idx].result.res
			&&
		   result.index == cases[idx].result.index
			&&
		   result.dir == cases[idx].result.dir
			&&
		   result.stat == cases[idx].result.stat
			&&
		   result.mode == cases[idx].result.mode
			&&
		   result.mpty == cases[idx].result.mpty
			&&
		   test_strcmp(result.number, cases[idx].result.number) == 0
			&&
		   result.toa == cases[idx].result.toa
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,%d,%d,%d,%d,\"%s\",%d)\t%s\n", result.res, result.index, result.dir, result.stat, result.mode, result.mpty, result.number, result.toa, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}
Example #10
0
/*!
 * \brief Enque an commands for 'Put active calls on hold and activate the waiting or held call.'
 * \param pvt -- pvt structure
 * \return 0 on success
 */
EXPORT_DEF int at_enque_flip_hold (struct cpvt* cpvt)
{
	static const at_queue_cmd_t cmds[] = {
		ATQ_CMD_DECLARE_ST(CMD_AT_CHLD_2, cmd_chld2),
		ATQ_CMD_DECLARE_ST(CMD_AT_CLCC, cmd_clcc),
		};

	return at_queue_insert_const(cpvt, cmds, ITEMS_OF(cmds), 1);
}
Example #11
0
	/*
	 * parse CSCA info in the following format:
	 * +CSCA: <SCA>,<TOSCA>
	 *  +CSCA: "+79139131234",145
	 *  +CSCA: "",145
	 */
	char delimiters[] = "\"\"";
	char * marks[STRLEN(delimiters)];

	if(mark_line(str, delimiters, marks) == ITEMS_OF(marks))
	{
		*csca = marks[0] + 1;
		marks[1][0] = 0;
		return 0;
	}

	return -1;
}

#/* */
EXPORT_DEF int at_parse_clcc(char* str, unsigned * call_idx, unsigned * dir, unsigned * state, unsigned * mode, unsigned * mpty, char ** number, unsigned * toa)
{
	/*
	 * +CLCC:<id1>,<dir>,<stat>,<mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]\r\n
	 *  ...
	 * +CLCC:<id1>,<dir>,<stat>,<mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]\r\n
	 *  examples
	 *   +CLCC: 1,1,4,0,0,"",145
	 *   +CLCC: 1,1,4,0,0,"+79139131234",145
	 *   +CLCC: 1,1,4,0,0,"0079139131234",145
	 *   +CLCC: 1,1,4,0,0,"+7913913ABCA",145
	 */
	char delimiters[] = ":,,,,,,";
	char * marks[STRLEN(delimiters)];

	*call_idx = 0;
	*dir = 0;
	*state = 0;
	*mode = 0;
	*mpty = 0;
	*number = "";
	*toa = 0;

	if(mark_line(str, delimiters, marks) == ITEMS_OF(marks))
	{
		if( sscanf(marks[0] + 1, "%u", call_idx) == 1
			&&
		    sscanf(marks[1] + 1, "%u", dir) == 1
			&&
		    sscanf(marks[2] + 1, "%u", state) == 1
			&&
		    sscanf(marks[3] + 1, "%u", mode) == 1
			&&
		    sscanf(marks[4] + 1, "%u", mpty) == 1
			&&
		    sscanf(marks[6] + 1, "%u", toa) == 1) 
		{
			marks[5]++;
			if(marks[5][0] == '"')
				marks[5]++;
			if(marks[6][-1] == '"')
				marks[6]--;
			*number = marks[5];
			marks[6][0] = 0;

			return 0;
		}
	}

	return -1;
}
Example #12
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "at_parse.h"			/* at_parse_*() */
#include "mutils.h"			/* ITEMS_OF() */


int ok = 0;
int faults = 0;

int test_strcmp(const char *pa, const char *pb)
{
	int retval;

	if (pa == NULL)
		pa = "";
	if (pb == NULL)
		pb = "";
	retval = strcmp(pa,pb);

	if (retval != 0) {
		int x = 0;
		while (pa[x] == pb[x] && pa[x] != 0) {
			x++;
		}
		printf("String '%s' and '%s' differs at "
		    "offset %d '%c' != '%c'\n", pa, pb, x, pa[x], pb[x]);
	}
	return (retval);
}

#/* */
void test_parse_cnum()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+CNUM: \"*Subscriber Number\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"Subscriber Number\",\"\",145", "" },
		{ "+CNUM: \"Subscriber Number\",,145", "" },
		{ "+CNUM: \"\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: ,\"\",145", "" },
		{ "+CNUM: ,,145", "" },
		{ "+CNUM: \"\",+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"\",+79139131234,145", "+79139131234" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cnum", input);
		res = at_parse_cnum(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cops()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+COPS: 0,0,\"TELE2\",0", "TELE2" },
		{ "+COPS: 0,0,\"TELE2,0", "TELE2" },
		{ "+COPS: 0,0,TELE2,0", "TELE2" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cops", input);
		res = at_parse_cops(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_creg()
{
	struct result {
		int	res;
		int	gsm_reg;
		int	gsm_reg_status;
		char 	* lac;
		char	* ci;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CREG: 2,1,9110,7E6", { 0, 1, 1, "9110", "7E6"} },
		{ "+CREG: 2,1,XXXX,AAAA", { 0, 1, 1, "XXXX", "AAAA"} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_creg", input);
		result.res = at_parse_creg(input, strlen(input), &result.gsm_reg, &result.gsm_reg_status, &result.lac, &result.ci);
		if(result.res == cases[idx].result.res
			&&
		   result.gsm_reg == cases[idx].result.gsm_reg
			&&
		   result.gsm_reg_status == cases[idx].result.gsm_reg_status
			&&
		   test_strcmp(result.lac, cases[idx].result.lac) == 0
			&&
		   test_strcmp(result.ci, cases[idx].result.ci) == 0
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,%d,\"%s\",\"%s\")\t%s\n", result.res, result.gsm_reg, result.gsm_reg_status, result.lac, result.ci, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}
Example #13
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "at_parse.h"			/* at_parse_*() */
#include "mutils.h"			/* ITEMS_OF() */


int ok = 0;
int faults = 0;

int test_strcmp(const char *pa, const char *pb)
{
	int retval;

	if (pa == NULL)
		pa = "";
	if (pb == NULL)
		pb = "";
	retval = strcmp(pa,pb);

	if (retval != 0) {
		int x = 0;
		while (pa[x] == pb[x] && pa[x] != 0) {
			x++;
		}
		printf("String '%s' and '%s' differs at "
		    "offset %d '%c' != '%c'\n", pa, pb, x, pa[x], pb[x]);
	}
	return (retval);
}

#/* */
void test_parse_cnum()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+CNUM: \"*Subscriber Number\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"Subscriber Number\",\"\",145", "" },
		{ "+CNUM: \"Subscriber Number\",,145", "" },
		{ "+CNUM: \"\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: ,\"\",145", "" },
		{ "+CNUM: ,,145", "" },
		{ "+CNUM: \"\",+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"\",+79139131234,145", "+79139131234" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cnum", input);
		res = at_parse_cnum(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cops()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+COPS: 0,0,\"TELE2\",0", "TELE2" },
		{ "+COPS: 0,0,\"TELE2,0", "TELE2" },
		{ "+COPS: 0,0,TELE2,0", "TELE2" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cops", input);
		res = at_parse_cops(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_creg()
{
	struct result {
		int	res;
		int	gsm_reg;
		int	gsm_reg_status;
		char 	* lac;
		char	* ci;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CREG: 2,1,9110,7E6", { 0, 1, 1, "9110", "7E6"} },
		{ "+CREG: 2,1,XXXX,AAAA", { 0, 1, 1, "XXXX", "AAAA"} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_creg", input);
		result.res = at_parse_creg(input, strlen(input), &result.gsm_reg, &result.gsm_reg_status, &result.lac, &result.ci);
		if(result.res == cases[idx].result.res
			&&
		   result.gsm_reg == cases[idx].result.gsm_reg
			&&
		   result.gsm_reg_status == cases[idx].result.gsm_reg_status
			&&
		   test_strcmp(result.lac, cases[idx].result.lac) == 0
			&&
		   test_strcmp(result.ci, cases[idx].result.ci) == 0
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,%d,\"%s\",\"%s\")\t%s\n", result.res, result.gsm_reg, result.gsm_reg_status, result.lac, result.ci, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cmti()
{
	static const struct test_case {
		const char	* input;
		int		result;
	} cases[] = {
		{ "+CMTI: \"ME\",41", 41 },
		{ "+CMTI: 0,111", 111 },
		{ "+CMTI: ", -1 },
	};
	unsigned idx = 0;
	char * input;
	int result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmti", input);
		result = at_parse_cmti(input);
		if(result == cases[idx].result) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d\t%s\n", result, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cmgr()
{
	struct result {
		const char	* res;
		char		* str;
		char 		* oa;
		str_encoding_t	oa_enc;
		char		* msg;
		str_encoding_t	msg_enc;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CMGR: \"REC READ\",\"+79139131234\",,\"10/12/05,22:00:04+12\"\r\n041F04400438043204350442", 
			{
				NULL,
				"\"REC READ\",\"+79139131234",
				"+79139131234",
				STR_ENCODING_7BIT,
				"041F04400438043204350442",
				STR_ENCODING_UNKNOWN
			}
		},
		{ "+CMGR: \"REC READ\",\"002B00370039003500330037003600310032003000350032\",,\"10/12/05,22:00:04+12\"\r\n041F04400438043204350442", 
			{
				NULL, 
				"\"REC READ\",\"002B00370039003500330037003600310032003000350032",
				"002B00370039003500330037003600310032003000350032", 
				STR_ENCODING_UNKNOWN,
				"041F04400438043204350442",
				STR_ENCODING_UNKNOWN
			}
		},
		{ "+CMGR: 0,,106\r\n07911111111100F3040B911111111111F200000121702214952163B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
			{
				NULL,
				"B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
				"+11111111112",
				STR_ENCODING_7BIT,
				"B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
				STR_ENCODING_7BIT_HEX_PAD_0
			} 
		},
		{ "+CMGR: 0,,159\r\n07919740430900F3440B912222222220F20008012180004390218C0500030003010031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
			{
				NULL,
				"0031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
				"+22222222022",
				STR_ENCODING_7BIT,
				"0031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
				STR_ENCODING_UCS2_HEX
			} 
		},
		{ "+CMGR: 0,,158\r\n07916407970970F6400A912222222222000041903021825180A0050003000301A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
			{
				NULL,
				"A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
				"+2222222222",
				STR_ENCODING_7BIT,
				"A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
				STR_ENCODING_7BIT_HEX_PAD_1,
			}
		},
		{ "+CMGR: 0,,55\r\n07912933035011804409D055F3DB5D060000411120712071022A080701030003990202A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
			{
				NULL,
				"A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
				"553",
				STR_ENCODING_7BIT,
				"A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
				STR_ENCODING_7BIT_HEX_PAD_5,
			}
		},
	};

	unsigned idx = 0;
	char * input;
	struct result result;
	char oa[200];
	char buffer_res[256];
	char buffer_dec[256];
	const char * msg;

	result.oa = oa;
	for(; idx < ITEMS_OF(cases); ++idx) {
		result.str = input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmgr", input);
		result.res = at_parse_cmgr(&result.str, strlen(result.str), result.oa, sizeof(oa), &result.oa_enc, &result.msg, &result.msg_enc);
		if( ((result.res == NULL && result.res == cases[idx].result.res) || test_strcmp(result.res, cases[idx].result.res) == 0)
			&&
		   test_strcmp(result.str, cases[idx].result.str) == 0
			&&
		   test_strcmp(result.oa, cases[idx].result.oa) == 0
			&&
		   result.oa_enc == cases[idx].result.oa_enc
			&&
		   test_strcmp(result.msg, cases[idx].result.msg) == 0
			&&
		   result.msg_enc == cases[idx].result.msg_enc
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		memset(buffer_res, 0, sizeof(buffer_res));
		memset(buffer_dec, 0, sizeof(buffer_dec));
		str_recode(RECODE_DECODE, result.msg_enc, result.msg, strlen(result.msg), buffer_res, sizeof(buffer_res));
		str_recode(RECODE_DECODE, cases[idx].result.msg_enc, cases[idx].result.msg, strlen(cases[idx].result.msg), buffer_dec, sizeof(buffer_dec));
		fprintf(stderr, " = '%s' ('%s','%s',%d,'%s',%d,'%s','%s')\t%s\n", result.res, result.str, result.oa, result.oa_enc, result.msg, result.msg_enc, buffer_res, buffer_dec, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cusd()
{
	struct result {
		int	res;
		int	type;
		char 	* cusd;
		int	dcs;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CUSD: 0,\"CF2135487D2E4130572D0682BB1A\",0", { 0, 0, "CF2135487D2E4130572D0682BB1A", 0} },
		{ "+CUSD: 1,\"CF2135487D2E4130572D0682BB1A\",1", { 0, 1, "CF2135487D2E4130572D0682BB1A", 1} },
		{ "+CUSD: 5", { 0, 5, "", -1} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cusd", input);
		result.res = at_parse_cusd(input, &result.type, &result.cusd, &result.dcs);
		if(result.res == cases[idx].result.res
			&&
		   result.type == cases[idx].result.type
			&&
		   result.dcs == cases[idx].result.dcs
			&&
		   test_strcmp(result.cusd, cases[idx].result.cusd) == 0
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,\"%s\",%d)\t%s\n", result.res, result.type, result.cusd, result.dcs, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}
Example #14
0
/* SMS sending */
EXPORT_DEF int at_enque_pdu(struct cpvt * cpvt, const char * pdu, attribute_unused const char * u1, attribute_unused unsigned u2, attribute_unused int u3, void ** id)
{
	char * ptr = (char *) pdu;
	char buf[8+25+1];
	at_queue_cmd_t at_cmd[] = {
		{ CMD_AT_CMGS,    RES_SMS_PROMPT, ATQ_CMD_FLAG_DEFAULT, { ATQ_CMD_TIMEOUT_2S, 0}  , NULL, 0 },
		{ CMD_AT_SMSTEXT, RES_OK,         ATQ_CMD_FLAG_DEFAULT, { ATQ_CMD_TIMEOUT_40S, 0} , NULL, 0 }
		};

	size_t length = strlen(pdu);
	size_t pdulen = length;

	int scalen = pdu_parse_sca(&ptr, &pdulen);
	
	if(scalen < 2 || length % 2 != 0)
	{
		return -EINVAL;
	}

	at_cmd[1].data = ast_malloc(length + 2);
	if(!at_cmd[1].data)
	{		
		return -ENOMEM;
	}

	at_cmd[1].length = length + 1;

	memcpy(at_cmd[1].data, pdu, length);
	at_cmd[1].data[length] = 0x1A;
	at_cmd[1].data[length+1] = 0x0;
		
	at_cmd[0].length = snprintf(buf, sizeof(buf), "AT+CMGS=%d\r", (int)(pdulen / 2));
	at_cmd[0].data = ast_strdup(buf);
	if(!at_cmd[0].data)
	{
		ast_free(at_cmd[1].data);
		return -ENOMEM;		
	}
			
/*		ast_debug (5, "[%s] PDU Head '%s'\n", PVT_ID(pvt), buf);
		ast_debug (5, "[%s] PDU Body '%s'\n", PVT_ID(pvt), at_cmd[1].data);
*/
	return at_queue_insert_task(cpvt, at_cmd, ITEMS_OF(at_cmd), 0, (struct at_queue_task **)id);
}
Example #15
0
static const char * parse_cmgr_text(char ** str, size_t len, char * oa, size_t oa_len, str_encoding_t * oa_enc, char ** msg, str_encoding_t * msg_enc)
{
	/*
	 * parse cmgr info in the following TEXT format:
	 * +CMGR: "<msg status>","+123456789",,timestamp<CR><LF>
	 * <message text><CR><LF><CR><LF>
	 * OK<CR><LF>
	 *	or
	 * +CMGR: "<msg status>","002B....",,timestamp<CR><LF>
	 * <message text><CR><LF><CR><LF>
	 * OK<CR><LF>
	 */

	char delimiters[] = ",,,\n";
	char * marks[STRLEN(delimiters)];
	size_t length;
	
	unsigned count = mark_line(*str, delimiters, marks);
	if(count == ITEMS_OF(marks))
	{
		/* unquote number */
		marks[0]++;
		if(marks[0][0] == '"')
			marks[0]++;
		if(marks[1][-1] == '"')
			marks[1]--;
		length = marks[1] - marks[0] + 1;
		if(oa_len < length)
			return "Not enought space for store number";
		*oa_enc = get_encoding(RECODE_DECODE, marks[0], length  - 1);
		marks[1][0] = 0;
		memcpy(oa, marks[0], length);

		*msg = marks[3] + 1;
		length = len - (*msg - *str);
		*msg_enc = get_encoding(RECODE_DECODE, *msg, length);
		return NULL;
	}
	else if(count > 0)
		*str = marks[count - 1];

	return "Can't parse +CMGR response text";
}
Example #16
0
EXPORT_DEF int at_parse_cpin (char* str, size_t len)
{
	static const struct {
		const char	* value;
		unsigned	length;
	} resp[] = {
		{ "READY", 5 },
		{ "SIM PIN", 7 },
		{ "SIM PUK", 7 },
	};

	unsigned idx;
	for(idx = 0; idx < ITEMS_OF(resp); idx++)
	{
		if(memmem (str, len, resp[idx].value, resp[idx].length) != NULL)
			return idx;
	}
	return -1;
}
Example #17
0
	/*
	 * parse RSSI info in the following format:
	 * ^MODE:<mode>,<submode>
	 */

	return sscanf (str, "^MODE:%d,%d", mode, submode) == 2 ? 0 : -1;
}

#/* */
EXPORT_DEF int at_parse_csca(char* str, char ** csca)
{
	/*
	 * parse CSCA info in the following format:
	 * +CSCA: <SCA>,<TOSCA>
	 *  +CSCA: "+79139131234",145
	 *  +CSCA: "",145
	 */
	char delimiters[] = "\"\"";
	char * marks[STRLEN(delimiters)];

	if(mark_line(str, delimiters, marks) == ITEMS_OF(marks))
	{
		*csca = marks[0] + 1;
		marks[1][0] = 0;
		return 0;
	}

	return -1;
}
Example #18
0
/*!
 * \brief Enque an activate commands 'Put active calls on hold and activate call x.'
 * \param cpvt -- cpvt structure
 * \return 0 on success
 */
EXPORT_DEF int at_enque_activate (struct cpvt* cpvt)
{
	at_queue_cmd_t cmds[] = {
		ATQ_CMD_DECLARE_DYN(CMD_AT_CHLD_2x),
		ATQ_CMD_DECLARE_ST(CMD_AT_CLCC, cmd_clcc),
		};
	int err;

	if (cpvt->state == CALL_STATE_ACTIVE)
		return 0;

	if (cpvt->state != CALL_STATE_ONHOLD && cpvt->state != CALL_STATE_WAITING)
	{
		ast_log (LOG_ERROR, "[%s] Imposible activate call idx %d from state '%s'\n", 
				PVT_ID(cpvt->pvt), cpvt->call_idx, call_state2str(cpvt->state));
		return -1;
	}


	err = at_fill_generic_cmd(&cmds[0], "AT+CHLD=2%d\r", cpvt->call_idx);
	if(err == 0)
		err = at_queue_insert(cpvt, cmds, ITEMS_OF(cmds), 1);
	return err;
}
Example #19
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "at_parse.h"			/* at_parse_*() */
#include "mutils.h"			/* ITEMS_OF() */


int ok = 0;
int faults = 0;

int test_strcmp(const char *pa, const char *pb)
{
	int retval;

	if (pa == NULL)
		pa = "";
	if (pb == NULL)
		pb = "";
	retval = strcmp(pa,pb);

	if (retval != 0) {
		int x = 0;
		while (pa[x] == pb[x] && pa[x] != 0) {
			x++;
		}
		printf("String '%s' and '%s' differs at "
		    "offset %d '%c' != '%c'\n", pa, pb, x, pa[x], pb[x]);
	}
	return (retval);
}

#/* */
void test_parse_cnum()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+CNUM: \"*Subscriber Number\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"Subscriber Number\",\"\",145", "" },
		{ "+CNUM: \"Subscriber Number\",,145", "" },
		{ "+CNUM: \"\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: ,\"\",145", "" },
		{ "+CNUM: ,,145", "" },
		{ "+CNUM: \"\",+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"\",+79139131234,145", "+79139131234" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cnum", input);
		res = at_parse_cnum(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}
EXPORT_DEF const char * dc_dtmf_setting2str(dc_dtmf_setting_t dtmf)
{
	return enum2str(dtmf, dtmf_values, ITEMS_OF(dtmf_values));
}
Example #21
0
/*!
 * \brief Enque commands for reading SMS
 * \param cpvt -- cpvt structure
 * \param index -- index of message in store
 * \param delete -- if non-zero also enque commands for delete message in store after reading
 * \return 0 on success
 */
EXPORT_DEF int at_enque_retrive_sms (struct cpvt* cpvt, int index, int delete)
{
	int err;
	at_queue_cmd_t cmds[] = {
		ATQ_CMD_DECLARE_DYN2(CMD_AT_CMGR, RES_CMGR),
		ATQ_CMD_DECLARE_DYN(CMD_AT_CMGD)
		};
	unsigned cmdsno = ITEMS_OF (cmds);

	err = at_fill_generic_cmd (&cmds[0], "AT+CMGR=%d\r", index);
	if (err)
		return err;

	if (delete)
	{
		err = at_fill_generic_cmd (&cmds[1], "AT+CMGD=%d\r\r", index);
		if(err)
		{
			ast_free (cmds[0].data);
			return err;
		}
	}
	else
EXPORT_DEF int dc_dtmf_str2setting(const char * value)
{
    return str2enum(value, dtmf_values, ITEMS_OF(dtmf_values));
}
	/* first set default values */
	memset(config, 0, sizeof(*config));

	ast_copy_string (config->context, "default", sizeof (config->context));
	ast_copy_string (config->exten, "", sizeof (config->exten));
	ast_copy_string (config->language, DEFAULT_LANGUAGE, sizeof (config->language));

	config->u2diag			= -1;
	config->resetdongle		=  1;
	config->callingpres		= -1;
	config->initstate		= DEV_STATE_STARTED;
	config->callwaiting 		= CALL_WAITING_AUTO;
	config->dtmf			= DC_DTMF_SETTING_RELAX;

	config->mindtmfgap		= DEFAULT_MINDTMFGAP;
	config->mindtmfduration		= DEFAULT_MINDTMFDURATION;
	config->mindtmfinterval		= DEFAULT_MINDTMFINTERVAL;
}

#/* */
EXPORT_DEF void dc_sconfig_fill(struct ast_config * cfg, const char * cat, struct dc_sconfig * config)
{
	struct ast_variable * v;

	/*  read config and translate to values */
	for (v = ast_variable_browse (cfg, cat); v; v = v->next)
	{
		if (!strcasecmp (v->name, "context"))
		{
			ast_copy_string (config->context, v->value, sizeof (config->context));
		}
		else if (!strcasecmp (v->name, "exten"))
		{
			ast_copy_string (config->exten, v->value, sizeof (config->exten));
		}
		else if (!strcasecmp (v->name, "language"))
		{
			ast_copy_string (config->language, v->value, sizeof (config->language));/* set channel language */
		}
		else if (!strcasecmp (v->name, "group"))
		{
			config->group = (int) strtol (v->value, (char**) NULL, 10);		/* group is set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "rxgain"))
		{
			config->rxgain = (int) strtol (v->value, (char**) NULL, 10);		/* rxgain is set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "txgain"))
		{
			config->txgain = (int) strtol (v->value, (char**) NULL, 10);		/* txgain is set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "u2diag"))
		{
			errno = 0;
			config->u2diag = (int) strtol (v->value, (char**) NULL, 10);		/* u2diag is set to -1 if invalid */
			if (config->u2diag == 0 && errno == EINVAL)
			{
				config->u2diag = -1;
			}
		}
		else if (!strcasecmp (v->name, "callingpres"))
		{
			config->callingpres = ast_parse_caller_presentation (v->value);
			if (config->callingpres == -1)
			{
				errno = 0;
				config->callingpres = (int) strtol (v->value, (char**) NULL, 10);/* callingpres is set to -1 if invalid */
				if (config->callingpres == 0 && errno == EINVAL)
				{
					config->callingpres = -1;
				}
			}
		}
		else if (!strcasecmp (v->name, "usecallingpres"))
		{
			config->usecallingpres = ast_true (v->value);		/* usecallingpres is set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "autodeletesms"))
		{
			config->autodeletesms = ast_true (v->value);		/* autodeletesms is set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "resetdongle"))
		{
			config->resetdongle = ast_true (v->value);		/* resetdongle is set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "disablesms"))
		{
			config->disablesms = ast_true (v->value);		/* disablesms is set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "smsaspdu"))
		{
			config->smsaspdu = ast_true (v->value);			/* send_sms_as_pdu us set to 0 if invalid */
		}
		else if (!strcasecmp (v->name, "disable"))
		{
			config->initstate = ast_true (v->value) ? DEV_STATE_REMOVED : DEV_STATE_STARTED;
		}
		else if (!strcasecmp (v->name, "initstate"))
		{
			int val = str2enum(v->value, dev_state_strs, ITEMS_OF(dev_state_strs));
			if(val == DEV_STATE_STOPPED || val == DEV_STATE_STARTED || val == DEV_STATE_REMOVED)
				config->initstate = val;
			else
				ast_log(LOG_ERROR, "Invalid value for 'initstate': '%s', must be one of 'stop' 'start' 'remove' default is 'start'\n", v->value);
		}
		else if (!strcasecmp (v->name, "callwaiting"))
		{
			if(strcasecmp(v->value, "auto"))
				config->callwaiting = ast_true (v->value);
		}
		else if (!strcasecmp (v->name, "dtmf"))
		{
			int val = dc_dtmf_str2setting(v->value);
			if(val >= 0)
				config->dtmf = val;
			else
				ast_log(LOG_ERROR, "Invalid value for 'dtmf': '%s', setting default 'relax'\n", v->value);
		}
		else if (!strcasecmp (v->name, "mindtmfgap"))
		{
			errno = 0;
			config->mindtmfgap = (int) strtol (v->value, (char**) NULL, 10);
			if ((config->mindtmfgap == 0 && errno == EINVAL) || config->mindtmfgap < 0)
			{
				ast_log(LOG_ERROR, "Invalid value for 'mindtmfgap' '%s', setting default %d\n", v->value, DEFAULT_MINDTMFGAP);
				config->mindtmfgap = DEFAULT_MINDTMFGAP;
			}
		}
		else if (!strcasecmp (v->name, "mindtmfduration"))
		{
			errno = 0;
			config->mindtmfduration = (int) strtol (v->value, (char**) NULL, 10);
			if ((config->mindtmfduration == 0 && errno == EINVAL) || config->mindtmfduration < 0)
			{
				ast_log(LOG_ERROR, "Invalid value for 'mindtmfgap' '%s', setting default %d\n", v->value, DEFAULT_MINDTMFDURATION);
				config->mindtmfduration = DEFAULT_MINDTMFDURATION;
			}
		}
		else if (!strcasecmp (v->name, "mindtmfinterval"))
		{
			errno = 0;
			config->mindtmfinterval = (int) strtol (v->value, (char**) NULL, 10);
			if ((config->mindtmfinterval == 0 && errno == EINVAL) || config->mindtmfinterval < 0)
			{
				ast_log(LOG_ERROR, "Invalid value for 'mindtmfinterval' '%s', setting default %d\n", v->value, DEFAULT_MINDTMFINTERVAL);
				config->mindtmfduration = DEFAULT_MINDTMFINTERVAL;
			}
		}
	}
}
Example #24
0
EXPORT_DEF int at_enque_sms (struct cpvt* cpvt, const char* destination, const char* msg, unsigned validity_minutes, int report_req, void ** id)
{
	ssize_t res;
	char buf[1024] = "AT+CMGS=\"";
	char pdu_buf[2048];
	pvt_t* pvt = cpvt->pvt;
	
	at_queue_cmd_t at_cmd[] = {
		{ CMD_AT_CMGS,    RES_SMS_PROMPT, ATQ_CMD_FLAG_DEFAULT, { ATQ_CMD_TIMEOUT_2S, 0}  , NULL, 0 },
		{ CMD_AT_SMSTEXT, RES_OK,         ATQ_CMD_FLAG_DEFAULT, { ATQ_CMD_TIMEOUT_40S, 0} , NULL, 0 }
		};

	if(pvt->use_pdu)
	{
		/* set default validity period */
		if(validity_minutes <= 0)
			validity_minutes = 3 * 24 * 60;
/*		res = pdu_build(pdu_buf, sizeof(pdu_buf), pvt->sms_scenter, destination, msg, validity_minutes, report_req);
*/
		res = pdu_build(pdu_buf, sizeof(pdu_buf), "", destination, msg, validity_minutes, report_req);
		if(res <= 0)
		{
			if(res == -E2BIG)
			{
			ast_verb (3, "[%s] SMS Message too long, PDU has limit 140 octets\n", PVT_ID(pvt));
			ast_log (LOG_WARNING, "[%s] SMS Message too long, PDU has limit 140 octets\n", PVT_ID(pvt));
			}
			/* TODO: complain on other errors */
			return res;
		}

		if(res > (int)(sizeof(pdu_buf) - 2))
			return -1;

		return at_enque_pdu(cpvt, pdu_buf, NULL, 0, 0, id);
	}
	else
	{
		at_cmd[0].length = 9;

		res = str_recode (RECODE_ENCODE, STR_ENCODING_UCS2_HEX, destination, strlen (destination), buf + at_cmd[0].length, sizeof(buf) - at_cmd[0].length - 3);
		if(res <= 0)
		{
			ast_log (LOG_ERROR, "[%s] Error converting SMS number to UCS-2\n", PVT_ID(pvt));
			return -4;
		}
		at_cmd[0].length += res;
		buf[at_cmd[0].length++] = '"';
		buf[at_cmd[0].length++] = '\r';
		buf[at_cmd[0].length] = '\0';
	}

	at_cmd[0].data = ast_strdup (buf);
	if(!at_cmd[0].data)
		return -ENOMEM;

	res = strlen (msg);

//	if(!pvt->use_pdu)
//	{
		if (pvt->use_ucs2_encoding)
		{
			/* NOTE: bg: i test limit of no response is 133, but for +CMS ERROR: ?  */
			/* message limit in 178 octet of TPDU (w/o SCA) Headers: Type(1)+MR(1)+DA(3..12)+PID(1)+DCS(1)+VP(0,1,7)+UDL(1) = 8..24 (usually 14)  */
			if(res > 70)
			{
				ast_log (LOG_ERROR, "[%s] SMS message too long, 70 symbols max\n", PVT_ID(pvt));
				return -4;
			}

			res = str_recode (RECODE_ENCODE, STR_ENCODING_UCS2_HEX, msg, res, pdu_buf, sizeof(pdu_buf) - 2);
			if (res < 0)
			{
				ast_free (at_cmd[0].data);
				ast_log (LOG_ERROR, "[%s] Error converting SMS to UCS-2: '%s'\n", PVT_ID(pvt), msg);
				return -4;
			}
			pdu_buf[res++] = 0x1a;
			pdu_buf[res] = 0;
			at_cmd[1].length = res;
		}
		else
		{
			if(res > 140)
			{
				ast_log (LOG_ERROR, "[%s] SMS message too long, 140 symbols max\n", PVT_ID(pvt));
				return -4;
			}

			at_cmd[1].length = snprintf (pdu_buf, sizeof(pdu_buf), "%.160s\x1a", msg);
		}
//	}

	at_cmd[1].data = ast_strdup(pdu_buf);
	if(!at_cmd[1].data)
	{
		ast_free(at_cmd[0].data);
		return -ENOMEM;
	}

	return at_queue_insert_task(cpvt, at_cmd, ITEMS_OF(at_cmd), 0, (struct at_queue_task **)id);
}
Example #25
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "at_parse.h"			/* at_parse_*() */
#include "mutils.h"			/* ITEMS_OF() */


int ok = 0;
int faults = 0;

int test_strcmp(const char *pa, const char *pb)
{
	int retval;

	if (pa == NULL)
		pa = "";
	if (pb == NULL)
		pb = "";
	retval = strcmp(pa,pb);

	if (retval != 0) {
		int x = 0;
		while (pa[x] == pb[x] && pa[x] != 0) {
			x++;
		}
		printf("String '%s' and '%s' differs at "
		    "offset %d '%c' != '%c'\n", pa, pb, x, pa[x], pb[x]);
	}
	return (retval);
}

#/* */
void test_parse_cnum()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+CNUM: \"*Subscriber Number\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"Subscriber Number\",\"\",145", "" },
		{ "+CNUM: \"Subscriber Number\",,145", "" },
		{ "+CNUM: \"\",\"+79139131234\",145", "+79139131234" },
		{ "+CNUM: ,\"\",145", "" },
		{ "+CNUM: ,,145", "" },
		{ "+CNUM: \"\",+79139131234\",145", "+79139131234" },
		{ "+CNUM: \"\",+79139131234,145", "+79139131234" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cnum", input);
		res = at_parse_cnum(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cops()
{
	static const struct test_case {
		const char	* input;
		const char	* result;
	} cases[] = {
		{ "+COPS: 0,0,\"TELE2\",0", "TELE2" },
		{ "+COPS: 0,0,\"TELE2,0", "TELE2" },
		{ "+COPS: 0,0,TELE2,0", "TELE2" },
	};
	unsigned idx = 0;
	char * input;
	const char * res;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cops", input);
		res = at_parse_cops(input);
		if(test_strcmp(res, cases[idx].result) == 0) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = \"%s\"\t%s\n", res, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_creg()
{
	struct result {
		int	res;
		int	gsm_reg;
		int	gsm_reg_status;
		char 	* lac;
		char	* ci;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CREG: 2,1,9110,7E6", { 0, 1, 1, "9110", "7E6"} },
		{ "+CREG: 2,1,XXXX,AAAA", { 0, 1, 1, "XXXX", "AAAA"} },
	};
	unsigned idx = 0;
	char * input;
	struct result result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_creg", input);
		result.res = at_parse_creg(input, strlen(input), &result.gsm_reg, &result.gsm_reg_status, &result.lac, &result.ci);
		if(result.res == cases[idx].result.res
			&&
		   result.gsm_reg == cases[idx].result.gsm_reg
			&&
		   result.gsm_reg_status == cases[idx].result.gsm_reg_status
			&&
		   test_strcmp(result.lac, cases[idx].result.lac) == 0
			&&
		   test_strcmp(result.ci, cases[idx].result.ci) == 0
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d (%d,%d,\"%s\",\"%s\")\t%s\n", result.res, result.gsm_reg, result.gsm_reg_status, result.lac, result.ci, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cmti()
{
	static const struct test_case {
		const char	* input;
		int		result;
	} cases[] = {
		{ "+CMTI: \"ME\",41", 41 },
		{ "+CMTI: 0,111", 111 },
		{ "+CMTI: ", -1 },
	};
	unsigned idx = 0;
	char * input;
	int result;
	const char * msg;
	
	for(; idx < ITEMS_OF(cases); ++idx) {
		input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmti", input);
		result = at_parse_cmti(input);
		if(result == cases[idx].result) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		fprintf(stderr, " = %d\t%s\n", result, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}

#/* */
void test_parse_cmgr()
{
	struct result {
		const char	* res;
		char		* str;
		char 		* oa;
		str_encoding_t	oa_enc;
		char		* msg;
		str_encoding_t	msg_enc;
	};
	static const struct test_case {
		const char	* input;
		struct result 	result;
	} cases[] = {
		{ "+CMGR: \"REC READ\",\"+79139131234\",,\"10/12/05,22:00:04+12\"\r\n041F04400438043204350442", 
			{
				NULL,
				"\"REC READ\",\"+79139131234",
				"+79139131234",
				STR_ENCODING_7BIT,
				"041F04400438043204350442",
				STR_ENCODING_UNKNOWN
			}
		},
		{ "+CMGR: \"REC READ\",\"002B00370039003500330037003600310032003000350032\",,\"10/12/05,22:00:04+12\"\r\n041F04400438043204350442", 
			{
				NULL, 
				"\"REC READ\",\"002B00370039003500330037003600310032003000350032",
				"002B00370039003500330037003600310032003000350032", 
				STR_ENCODING_UNKNOWN,
				"041F04400438043204350442",
				STR_ENCODING_UNKNOWN
			}
		},
		{ "+CMGR: 0,,106\r\n07911111111100F3040B911111111111F200000121702214952163B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
			{
				NULL,
				"B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
				"+11111111112",
				STR_ENCODING_7BIT,
				"B1582C168BC562B1984C2693C96432994C369BCD66B3D96C369BD168341A8D46A3D168B55AAD56ABD56AB59ACD66B3D96C369BCD76BBDD6EB7DBED76BBE170381C0E87C3E170B95C2E97CBE572B91C0C0683C16030180C",
				STR_ENCODING_7BIT_HEX_PAD_0
			} 
		},
		{ "+CMGR: 0,,159\r\n07919740430900F3440B912222222220F20008012180004390218C0500030003010031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
			{
				NULL,
				"0031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
				"+22222222022",
				STR_ENCODING_7BIT,
				"0031003100310031003100310031003100310031003200320032003200320032003200320032003200330033003300330033003300330033003300330034003400340034003400340034003400340034003500350035003500350035003500350035003500360036003600360036003600360036003600360037003700370037003700370037",
				STR_ENCODING_UCS2_HEX
			} 
		},
		{ "+CMGR: 0,,158\r\n07916407970970F6400A912222222222000041903021825180A0050003000301A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
			{
				NULL,
				"A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
				"+2222222222",
				STR_ENCODING_7BIT,
				"A9E5391D14060941439015240409414290102404094142901024040941429010240409414290106405594142901564055941429012A40429AD4AABD22A7481AC56101264455A915624C80AB282AC20A1D06A0559415610D20A4282AC2024C80AB282AC202BC80AB282AC2E9012B4042D414A90D2055282942E90D20502819420254809528294",
				STR_ENCODING_7BIT_HEX_PAD_1,
			}
		},
		{ "+CMGR: 0,,55\r\n07912933035011804409D055F3DB5D060000411120712071022A080701030003990202A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
			{
				NULL,
				"A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
				"553",
				STR_ENCODING_7BIT,
				"A09976D7E9E5390B640FB3D364103DCD668364B3562CD692C1623417",
				STR_ENCODING_7BIT_HEX_PAD_5,
			}
		},
	};

	unsigned idx = 0;
	char * input;
	struct result result;
	char oa[200];
	char buffer_res[256];
	char buffer_dec[256];
	const char * msg;

	result.oa = oa;
	for(; idx < ITEMS_OF(cases); ++idx) {
		result.str = input = strdup(cases[idx].input);
		fprintf(stderr, "%s(\"%s\")...", "at_parse_cmgr", input);
		result.res = at_parse_cmgr(&result.str, strlen(result.str), result.oa, sizeof(oa), &result.oa_enc, &result.msg, &result.msg_enc);
		if( ((result.res == NULL && result.res == cases[idx].result.res) || test_strcmp(result.res, cases[idx].result.res) == 0)
			&&
		   test_strcmp(result.str, cases[idx].result.str) == 0
			&&
		   test_strcmp(result.oa, cases[idx].result.oa) == 0
			&&
		   result.oa_enc == cases[idx].result.oa_enc
			&&
		   test_strcmp(result.msg, cases[idx].result.msg) == 0
			&&
		   result.msg_enc == cases[idx].result.msg_enc
			) {
			msg = "OK";
			ok++;
		} else {
			msg = "FAIL";
			faults++;
		}
		memset(buffer_res, 0, sizeof(buffer_res));
		memset(buffer_dec, 0, sizeof(buffer_dec));
		str_recode(RECODE_DECODE, result.msg_enc, result.msg, strlen(result.msg), buffer_res, sizeof(buffer_res));
		str_recode(RECODE_DECODE, cases[idx].result.msg_enc, cases[idx].result.msg, strlen(cases[idx].result.msg), buffer_dec, sizeof(buffer_dec));
		fprintf(stderr, " = '%s' ('%s','%s',%d,'%s',%d,'%s','%s')\t%s\n", result.res, result.str, result.oa, result.oa_enc, result.msg, result.msg_enc, buffer_res, buffer_dec, msg);
		free(input);
	}
	fprintf(stderr, "\n");
}
Example #26
0
/*!
 * \brief Enque initialization commands
 * \param cpvt -- cpvt structure
 * \param from_command -- begin initialization from this command in list
 * \return 0 on success
 */
EXPORT_DEF int at_enque_initialization(struct cpvt* cpvt, at_cmd_t from_command)
{
	static const char cmd2[] = "ATZ\r";
	static const char cmd3[] = "ATE0\r";

	static const char cmd5[] = "AT+CGMI\r";
	static const char cmd6[] = "AT+CSCA?\r";
	static const char cmd7[] = "AT+CGMM\r";
	static const char cmd8[] = "AT+CGMR\r";

	static const char cmd9[] = "AT+CMEE=0\r";
	static const char cmd10[] = "AT+CGSN\r";
	static const char cmd11[] = "AT+CIMI\r";
	static const char cmd12[] = "AT+CPIN?\r";

	static const char cmd13[] = "AT+COPS=0,0\r";
	static const char cmd14[] = "AT+CREG=2\r";
	static const char cmd15[] = "AT+CREG?\r";
	static const char cmd16[] = "AT+CNUM\r";

	static const char cmd17[] = "AT^CVOICE?\r";
//	static const char cmd18[] = "AT+CLIP=0\r";
	static const char cmd19[] = "AT+CSSN=1,1\r";
	static const char cmd21[] = "AT+CSCS=\"UCS2\"\r";

	static const char cmd22[] = "AT+CPMS=\"ME\",\"ME\",\"ME\"\r";
	static const char cmd23[] = "AT+CNMI=2,1,0,0,0\r";
	static const char cmd24[] = "AT+CSQ\r";

	static const at_queue_cmd_t st_cmds[] = {
		ATQ_CMD_DECLARE_ST(CMD_AT, cmd_at),
		ATQ_CMD_DECLARE_ST(CMD_AT_Z, cmd2),		/* optional,  reload configuration */
		ATQ_CMD_DECLARE_ST(CMD_AT_E, cmd3),		/* disable echo */
		ATQ_CMD_DECLARE_DYN(CMD_AT_U2DIAG),		/* optional, Enable or disable some devices */
		ATQ_CMD_DECLARE_ST(CMD_AT_CGMI, cmd5),		/* Getting manufacturer info */

		ATQ_CMD_DECLARE_ST(CMD_AT_CGMM, cmd7),		/* Get Product name */
		ATQ_CMD_DECLARE_ST(CMD_AT_CGMR, cmd8),		/* Get software version */
		ATQ_CMD_DECLARE_ST(CMD_AT_CMEE, cmd9),		/* set MS Error Report to 'ERROR' only  TODO: change to 1 or 2 and add support in response handlers */

		ATQ_CMD_DECLARE_ST(CMD_AT_CGSN, cmd10),		/* IMEI Read */
		ATQ_CMD_DECLARE_ST(CMD_AT_CIMI, cmd11),		/* IMSI Read */
		ATQ_CMD_DECLARE_ST(CMD_AT_CPIN, cmd12),		/* check is password authentication requirement and the remainder validation times */
		ATQ_CMD_DECLARE_ST(CMD_AT_COPS_INIT, cmd13),	/* Read operator name */

		ATQ_CMD_DECLARE_STI(CMD_AT_CREG_INIT,cmd14),	/* GSM registration status setting */
		ATQ_CMD_DECLARE_ST(CMD_AT_CREG, cmd15),		/* GSM registration status */
		ATQ_CMD_DECLARE_ST(CMD_AT_CNUM, cmd16),		/* Get Subscriber number */
		ATQ_CMD_DECLARE_ST(CMD_AT_CVOICE, cmd17),	/* read the current voice mode, and return sampling rate、data bit、frame period */

		ATQ_CMD_DECLARE_ST(CMD_AT_CSCA, cmd6),		/* Get SMS Service center address */
//		ATQ_CMD_DECLARE_ST(CMD_AT_CLIP, cmd18),		/* disable  Calling line identification presentation in unsolicited response +CLIP: <number>,<type>[,<subaddr>,<satype>[,[<alpha>][,<CLI validitity>]] */
		ATQ_CMD_DECLARE_ST(CMD_AT_CSSN, cmd19),		/* activate Supplementary Service Notification with CSSI and CSSU */
		ATQ_CMD_DECLARE_DYN(CMD_AT_CMGF),		/* Set Message Format */

		ATQ_CMD_DECLARE_STI(CMD_AT_CSCS, cmd21),	/* UCS-2 text encoding */

		ATQ_CMD_DECLARE_ST(CMD_AT_CPMS, cmd22),		/* SMS Storage Selection */
			/* pvt->initialized = 1 after successful of CMD_AT_CNMI */
		ATQ_CMD_DECLARE_ST(CMD_AT_CNMI, cmd23),		/* New SMS Notification Setting +CNMI=[<mode>[,<mt>[,<bm>[,<ds>[,<bfr>]]]]] */
		ATQ_CMD_DECLARE_ST(CMD_AT_CSQ, cmd24),		/* Query Signal quality */
		};
	unsigned in, out;
	int begin = -1;
	int err;
	char * ptmp1 = NULL;
	char * ptmp2 = NULL;
	pvt_t * pvt = cpvt->pvt;
	at_queue_cmd_t cmds[ITEMS_OF(st_cmds)];

	/* customize list */
	for(in = out = 0; in < ITEMS_OF(st_cmds); in++)
	{
		if(begin == -1)
		{
			if(st_cmds[in].cmd == from_command)
				begin = in;
			else
				continue;
		}

		if(st_cmds[in].cmd == CMD_AT_Z && !CONF_SHARED(pvt, resetdongle))
			continue;
		if(st_cmds[in].cmd == CMD_AT_U2DIAG && CONF_SHARED(pvt, u2diag) == -1)
			continue;

		memcpy(&cmds[out], &st_cmds[in], sizeof(st_cmds[in]));

		if(cmds[out].cmd == CMD_AT_U2DIAG)
		{
			err = at_fill_generic_cmd(&cmds[out], "AT^U2DIAG=%d\r", CONF_SHARED(pvt, u2diag));
			if(err)
				goto failure;
			ptmp1 = cmds[out].data;
		}
		else if(cmds[out].cmd == CMD_AT_CMGF)
		{
			err = at_fill_generic_cmd(&cmds[out], "AT+CMGF=%d\r", CONF_SHARED(pvt, smsaspdu) ? 0 : 1);
			if(err)
				goto failure;
			ptmp2 = cmds[out].data;
		}
		if(cmds[out].cmd == from_command)
			begin = out;
		out++;
	}

	if(out > 0)
		return at_queue_insert(cpvt, cmds, out, 0);
	return 0;
failure:
	if(ptmp1)
		ast_free(ptmp1);
	if(ptmp2)
		ast_free(ptmp2);
	return err;
}