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; }
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); }
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; }