Beispiel #1
0
static int
__print(const char* cmd, const char* format, va_list ap) {
	yldynb_t  d;
	yldynb_t  pdu;
	int	  r = -1;

	yldynb_init(&d, 4096);
	yldynb_init(&pdu, 4096);

	while (1) {
		r = vsnprintf((char*)yldynb_buf(&d),
			      yldynb_freesz(&d),
			      format,
			      ap);
		if (r < 0)
			goto bail;
		if (r < yldynb_limit(&d))
			break; /* success */
		yldynb_expand(&d);
	}
	d.sz = r;

	if (0 > pdu_build(&pdu,
			  (unsigned char*)cmd,
			  yldynb_buf(&d),
			  yldynb_sz(&d)))
		goto bail;

	if (0 > sock_send(_s, yldynb_buf(&pdu), yldynb_sz(&pdu)))
		goto bail;

	yldynb_clean(&pdu);
	yldynb_clean(&d);
	return r;

 bail:
	yldynb_clean(&pdu);
	yldynb_clean(&d);
	return -1;
}
Beispiel #2
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);
}
Beispiel #3
0
static int
_cmd_autocomp(const unsigned char* data, unsigned int sz) {
	int	       r;
	yldynb_t       b;     /* response data buffer */
	yldynb_t       pref;
	const char*    cmd;
	yldynbstr_init(&b, 4096);
	yldynb_init(&pref, 4096);
	yldynb_append(&pref, data, sz);
	yldynb_append(&pref, (unsigned char*)"", 1); /* add trailing 0 */

	r = ylsym_auto_complete((char*)yldynb_buf(&pref),
				(char*)yldynb_buf(&b),
				yldynb_freesz(&b));
	 /* +1 for tailing 0 */
	yldynb_setsz(&b, strlen((char*)yldynbstr_string(&b)) + 1);

	switch (r) {
	case 0: {
		if (yldynbstr_len(&b) > 0)
			cmd = CMD_AUTOCOMP_MORE;
		else {
			/* candidatess */
			/* we need to retrieve candidates.. */
			int	       num, i;
			unsigned int   maxlen;
			char**	       pp;
			num = ylsym_nr_candidates((char*)yldynb_buf(&pref),
						  &maxlen);
			assert(num > 1);
			pp = malloc(sizeof(char*) * num);
			if (!pp) {
				printf("Fail to alloc memory : %d\n", num);
				assert(0);
			}
			for (i=0; i<num; i++) {
				pp[i] = malloc(maxlen+1);
				if (!pp[i]) {
					printf("Fail to alloc memory : %d\n",
					       maxlen + 1);
					assert(0);
				}
			}
			i = ylsym_candidates((char*)yldynb_buf(&pref),
					     pp,
					     num,
					     maxlen+1);
			assert(i==num);

			yldynbstr_reset(&b);
			for (i=0; i<num; i++) {
				yldynbstr_append(&b,
						 "%s%s\n",
						 yldynb_buf(&pref),
						 pp[i]);
				free(pp[i]);
			}
			free(pp);
			cmd = CMD_AUTOCOMP_PRINT;
		}
	} break;

	case 1: {
		cmd = CMD_AUTOCOMP_COMP;
	} break;

	case 2: {
		cmd = CMD_AUTOCOMP_PRINT;
		yldynbstr_reset(&b); /* nothing to print */
	} break;

	default:
		printf("Internal error to try auto-completion.\n"
		       " Out of memory?\n");
		assert(0);
	}

	{ /* Just scope */
		/* pref is used. so reuse it as pdu buffer */
		yldynb_t* pdu = &pref;
		if (0 > pdu_build(pdu,
				  (unsigned char*)cmd,
				  yldynb_buf(&b),
				  yldynbstr_len(&b)))
			goto bail;

		if (0 > send_response(yldynb_buf(pdu), yldynb_sz(pdu)))
			goto bail;
	}

	yldynb_clean(&b);
	yldynb_clean(&pref);
	return 0;

 bail:
	yldynb_clean(&b);
	yldynb_clean(&pref);
	return -1;
}