/* TODO: complete translation from gsm to ascii and ascii to gsm handle sending/receiving multiple text messages and checking length of messages*/ /*#include "dat.h"#include "fns.h"#include "error.h"#include "version.h"#include "mp.h"#include "libsec.h"#include "keyboard.h"*/#include <stdio.h>#include <cutils/sockets.h>#include <stdlib.h>#include <telephony/ril.h>#include <cutils/jstring.h>#include <arpa/inet.h>#include <libgen.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h> #define RESPONSE_SOLICITED 0#define RESPONSE_UNSOLICITED 1 /* Parcel-handling code */#define PAD_SIZE(s) (((s)+3)&~3) struct parcel_t { char *data; size_t offset; size_t capacity; size_t size;}; void parcel_init(struct parcel_t *p){ p->data = malloc(sizeof(int32_t)); // arbitrary size to start with p->size = 0; p->capacity = sizeof(int32_t); p->offset = 0;} int parcel_grow(struct parcel_t *p, size_t size){ char *new = realloc(p->data, p->capacity + size); if(new == NULL) { return -1; } p->data = new; p->capacity += size; return 0;} int32_t parcel_r_int32(struct parcel_t *p){ int32_t ret; ret = *((int32_t *) (p->data + p->offset)); p->offset += sizeof(int32_t); return ret;} int parcel_w_int32(struct parcel_t *p, int32_t val){ for(;;) { printf("parcel_w_int32(%d): offset = %d, cap = %d, size = %d\n", val, p->offset, p->capacity, p->size); if(p->offset + sizeof(int32_t) < p->capacity) { // There's enough space *((int32_t *) (p->data + p->offset)) = val; p->offset += sizeof(int32_t); p->size += sizeof(int32_t); break; } else { // Grow data and retry if(parcel_grow(p, sizeof(int32_t)) == -1) { return -1; } } } return 0;} int parcel_w_string(struct parcel_t *p, char *str){ char16_t *s16; size_t s16_len; size_t len; if(str == NULL) { parcel_w_int32(p, -1); return 0; } s16 = strdup8to16(str, &s16_len); if(parcel_w_int32(p, s16_len) == -1) { return -1; } len = (s16_len + 1) * sizeof(char16_t); for(;;) { size_t padded = PAD_SIZE(len); printf("parcel_w_string(\"%s\"): offset %d, cap %d, size %d\n", str, p->offset, p->capacity, p->size); if(p->offset + len < p->capacity) { // There's enough space memcpy(p->data + p->offset, s16, s16_len * sizeof(char16_t)); *((char16_t *) (p->data + p->offset + len)) = 0; p->offset += padded; p->size += padded; if (padded != len) { printf("Writing %ld bytes, padded to %ld\n", len, padded);#if BYTE_ORDER == BIG_ENDIAN static const uint32_t mask[4] = { 0x00000000, 0xffffff00, 0xffff0000, 0xff000000 };#endif#if BYTE_ORDER == LITTLE_ENDIAN static const uint32_t mask[4] = { 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff };#endif //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len], // *reinterpret_cast<void**>(data+padded-4)); *((uint32_t*)(p->data+p->offset+padded-4)) &= mask[padded-len]; } break; } else { // Grow data and retry if(parcel_grow(p, padded) == -1) { free(s16); return -1; } } } free(s16); return 0;} char *parcel_r_string(struct parcel_t *p){ char *ret; int len = parcel_r_int32(p); printf("parcel_r_string: len = %d\n", len); ret = strndup16to8((char16_t *) (p->data + p->offset), len); p->offset += PAD_SIZE((len + 1) * sizeof(char16_t)); return ret;} size_t parcel_data_avail(struct parcel_t *p){ return (p->size - p->offset);} /* Received SMS - we get a hex string representation of the data. Roughly, the layout of the data is: 1 byte - length of SMS center information 1 byte - the format of the number (91 is the standard) (length above - 1) bytes - the number, nibble-swapped and padded with an f if needed 1 byte - properties of the message, generally we can ignore this 1 byte - length of sender number (in digits, not bytes) variable bytes - sender number, nibble-swapped and padded if needed 1 byte - protocol identifier - can ignore this probably 1 byte - data coding scheme - again can hopefully be ignored 7 bytes - timestamp, again nibble-swapped: y, m, d, h, m, s, timezone * timezone is in units of +15 min vs. GMT. If most sig. bit is 1, value is in units of -15 min vs. GMT. 1 byte - length of message in characters (NOT in bytes) rest of bytes - message. if ASCII 7-bit, compacted to save space through an encoding mechanism. For more information see http://www.dreamfabric.com/sms/ or GSM 03.38*/ struct recvd_sms { char *src_num; char *service_center; char *msg; char *timestamp;}; char gsm_to_ascii(char gsm);int decode_sms(char *hexstr, struct recvd_sms *sms);void acknowledge_sms(int fd);void send_sms(int fd, char *smsc_pdu, char *pdu);void usage(char *name);void loop_for_data(int fd); /* SMS-related functions */char gsm_to_ascii(char gsm){ switch(gsm) { case '\0': return '@'; }} char *hexify(char *bytes, size_t len){ char *hexarray[256]; int i, j; char *ret; for(i = 0; i < 256; i++) { hexarray[i] = (char *) malloc(3 * sizeof(char)); snprintf(hexarray[i], 3, "%02x", i); } ret = (char *) malloc((len * 2 + 1) * sizeof(char)); for(i = 0, j = 0; i < len; i++, j += 2) { ret[j] = hexarray[(unsigned char) bytes[i]][0]; ret[j + 1] = hexarray[(unsigned char) bytes[i]][1]; } ret[j] = '\0'; return ret;} int decode_sms(char *hexstr, struct recvd_sms *sms){ int smsc_len, src_len, curpos, msg_len; char *endptr; char **bytes; char *service_center, *src_num, *timestamp, *msg; int len, i, j, oldbits, numoldbits; char *msgbytes; /* first, split the string up into hex representations of the bytes-- this makes things much easier overall */ len = strlen(hexstr); if(len % 2 != 0) { fprintf(stderr, "malformed hex string passed to decode_sms\n"); return -1; } bytes = (char **) malloc((len / 2) * sizeof(char *)); for(i = 0; i < len / 2; i++) { bytes[i] = (char *) malloc(3 * sizeof(char)); bytes[i][0] = hexstr[i * 2]; bytes[i][1] = hexstr[i * 2 + 1]; bytes[i][2] = '\0'; } // decode the service center number smsc_len = strtol(bytes[0], &endptr, 16); if(strcmp(bytes[1], "91")) { fprintf(stderr, "unsupported number format for sender: %s", bytes[1]); } service_center = (char *) malloc((smsc_len) * sizeof(char)); service_center[0] = '\0'; for(i = 2, j = 0; i < smsc_len + 1; i++, j += 2) { // number is nibble-swapped service_center[j] = bytes[i][1]; if(bytes[i][0] == 'f') { // num may be padded with 'f' at end service_center[j + 1] = '\0'; } else { service_center[j + 1] = bytes[i][0]; } } service_center[j] = '\0'; curpos = i; sms->service_center = service_center; // next, decode the sender's number src_len = strtol(bytes[curpos + 1], NULL, 16); src_num = (char *) malloc((src_len + 1) * sizeof(char)); // convert src_len from # of digits to # of bytes src_len = (src_len % 2 == 0) ? src_len : src_len + 1; src_len = src_len / 2; if(strcmp(bytes[curpos + 2], "91")) { fprintf(stderr, "unsupported number format for sender: %s", bytes[curpos + 2]); } for(i = curpos + 3, j = 0; i < curpos + 3 + src_len; i++, j += 2) { // number is nibble-swapped src_num[j] = bytes[i][1]; if(bytes[i][0] == 'f') { // num may be padded with 'f' at end src_num[j + 1] = '\0'; } else { src_num[j + 1] = bytes[i][0]; } } src_num[j] = '\0'; sms->src_num = src_num; curpos = i; // Timestamp timestamp = (char *) malloc(9 * sizeof(char)); for(i = curpos + 2, j = 0; i < curpos + 9; i++, j += 2) { // number is nibble-swapped timestamp[j] = bytes[i][1]; timestamp[j + 1] = bytes[i][0]; } curpos = i; timestamp[j] = '\0'; sms->timestamp = timestamp; // Message msg = (char *) malloc(strtol(bytes[curpos], NULL, 16) * sizeof(char)); msg_len = len / 2 - (curpos + 1); msgbytes = (char *) malloc((msg_len) * sizeof(char)); for(i = curpos + 1, j = 0; i < len / 2, j < msg_len; i++, j++) { msgbytes[j] = strtol(bytes[i], NULL, 16); } // convert message to 8-bit ASCII oldbits = 0; numoldbits = 0; for(i = 0, j = 0; i < msg_len; i++, j++) { int numbits = (i % 7) + 1; int newbits; newbits = msgbytes[i] >> (8 - numbits); newbits &= (1 << numbits) - 1; msgbytes[i] = msgbytes[i] & ((1 << (8 - numbits)) - 1); msgbytes[i] = msgbytes[i] << numoldbits; msg[j] = msgbytes[i] | oldbits; // GSM alphabet is different than ASCII alphabet msg[j] = gsm_to_ascii(msg[j]); if(numbits == 7) { msg[j + 1] = newbits; j++; newbits = 0; numbits = 0; } oldbits = newbits; numoldbits = numbits; } msg[j] = '\0'; sms->msg = msg; // cleanup for(i = 0; i < len / 2; i++) { free(bytes[i]); } free(bytes); free(msgbytes); return 0;} char *encode_sms(char *destnum, char *msg){ int i, j, actual_dest_len, enc_msg_len, ret_len; char dest_len[3]; char *dest; char *enc_msg, *final_msg, *ret; // dest_len is the hex representation of the length of the phone # snprintf(dest_len, 3, "%02x", strlen(destnum)); actual_dest_len = (strlen(destnum) % 2 == 0) ? strlen(destnum) : strlen(destnum) + 1; dest = (char *) malloc((actual_dest_len + 1) * sizeof(char)); for(i = 0; i < actual_dest_len; i += 2) { if(destnum[i + 1] != '\0') { dest[i] = destnum[i + 1]; } else { dest[i] = 'f'; } dest[i + 1] = destnum[i]; } dest[i] = '\0'; printf("dest = %s\n", dest); enc_msg_len = strlen(msg) - (strlen(msg) / 8); enc_msg = (char *) malloc((enc_msg_len + 1) * sizeof(char)); for(i = 0, j = 0; i < strlen(msg); i++, j++) { int numbits = (i + 1) % 8; char bits; if(numbits == 0) { j--; continue; } bits = msg[i + 1] & ((1 << numbits) - 1); enc_msg[j] = msg[i] >> numbits - 1; printf("once shifted by %d: %hhx\n", numbits, enc_msg[j]); enc_msg[j] = enc_msg[j] | (bits << (8 - numbits)); printf("bits << (8 - numbits) %hhx\n", bits << (8 - numbits)); printf("%hhx\n", enc_msg[j]); fflush(stdout); } final_msg = hexify(enc_msg, enc_msg_len); ret_len = 14 + strlen(dest) + strlen(final_msg); ret = (char *) malloc((ret_len + 1) * sizeof(char)); // FIXME: too much of the sent msg is hardcoded snprintf(ret, ret_len + 1, "0120%s91%s0000%02x%s", dest_len, dest, strlen(msg), final_msg); printf("%s\n", ret); free(enc_msg); free(final_msg); free(dest); return ret;} /* functions that actually belong here */ void usage(char *name){ printf("%s command [arguments]\n", name); printf("Commands:\n"); printf("a: activate data network\n"); printf("d <number>: dial a number\n"); printf("t <number> <msg>: send an SMS message\n");} void interpret_sol_response(struct parcel_t *p, int fd){ int seq, error, i; seq = parcel_r_int32(p); error = parcel_r_int32(p); printf("solicited: seq = %d error = %d\n", seq, error); printf("%d bytes left\n", parcel_data_avail(p)); if(seq == 0) { if(!parcel_data_avail(p)) return; int numstr; numstr = parcel_r_int32(p); printf("numstr = %d\n", numstr); for(i = 0; i < numstr; i++) { printf("%s\n", parcel_r_string(p)); } }} void interpret_unsol_response(struct parcel_t *p, int fd){ int resp_type; resp_type = parcel_r_int32(p); printf("unsolicited: type = %d, data left = %d\n", resp_type, parcel_data_avail(p)); if(resp_type == RIL_UNSOL_RESPONSE_NEW_SMS) { struct recvd_sms sms; decode_sms(parcel_r_string(p), &sms); printf("Got SMS: %s from %s (service center %s)\n", sms.msg, sms.src_num, sms.service_center); acknowledge_sms(fd); }} void loop_for_data(int fd){ for(;;) { int msglen, readlen, type, i; char *buf; struct parcel_t p; void *pdata; parcel_init(&p); if(read(fd, &msglen, sizeof(msglen)) != sizeof(msglen)) { fprintf(stderr, "EOF while reading parcel length"); } msglen = ntohl(msglen); buf = (char *) malloc(msglen * sizeof(char)); readlen = read(fd, buf, msglen); if(readlen != msglen) { fprintf(stderr, "msglen = %d readlen = %d\n", msglen, readlen); fprintf(stderr, "got too much or not enough data, aborting\n"); return; } for(i = 0; i < readlen; i++) { printf("%02x", buf[i]); } printf("\n"); parcel_grow(&p, msglen); memcpy(p.data, buf, msglen); p.size = msglen; printf("Received %d bytes of data from rild.\n", msglen); type = parcel_r_int32(&p); if(type == RESPONSE_SOLICITED) { interpret_sol_response(&p, fd); } else { interpret_unsol_response(&p, fd); } free(buf); }} void dial(struct parcel_t *p, int fd, char *number){ int pktlen, ret; parcel_w_int32(p, RIL_REQUEST_DIAL); parcel_w_int32(p, 0); parcel_w_string(p, number); parcel_w_int32(p, 0); parcel_w_int32(p, 0); pktlen = htonl(p->size); ret = write(fd, (void *)&pktlen, sizeof(pktlen)); if(ret < 0) perror("write failed"); ret = write(fd, p->data, p->size); if(ret < 0) perror("write failed");} void activate_net(struct parcel_t *p, int fd){ int pktlen, ret, i; parcel_w_int32(p, RIL_REQUEST_SETUP_DATA_CALL); // request ID parcel_w_int32(p, 0); // seq number (?) parcel_w_int32(p, 7); // undocumented magic. parcel_w_string(p, "1"); // CDMA or GSM. 1 = GSM parcel_w_string(p, "0"); // data profile. 0 = default parcel_w_string(p, "wap.cingular"); // APN name parcel_w_string(p, "WAP@CINGULARGPRS.COM"); // APN user parcel_w_string(p, "cingular1"); // APN passwd parcel_w_string(p, "0"); // auth type. 0 usually for(i = 0; i < p->size; i++) { printf("%02x", p->data[i]); }Lines 1–500 of 588. Load more
/* TODO: complete translation from gsm to ascii and ascii to gsm handle sending/receiving multiple text messages and checking length of messages */ /*#include "dat.h" #include "fns.h" #include "error.h" #include "version.h" #include "mp.h" #include "libsec.h" #include "keyboard.h"*/ #include <stdio.h> #include <cutils/sockets.h> #include <stdlib.h> #include <telephony/ril.h> #include <cutils/jstring.h> #include <arpa/inet.h> #include <libgen.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define RESPONSE_SOLICITED 0 #define RESPONSE_UNSOLICITED 1 /* Parcel-handling code */ #define PAD_SIZE(s) (((s)+3)&~3) struct parcel_t { char *data; size_t offset; size_t capacity; size_t size; }; void parcel_init(struct parcel_t *p) { p->data = malloc(sizeof(int32_t)); // arbitrary size to start with p->size = 0; p->capacity = sizeof(int32_t); p->offset = 0; } int parcel_grow(struct parcel_t *p, size_t size) { char *new = realloc(p->data, p->capacity + size); if(new == NULL) { return -1; } p->data = new; p->capacity += size; return 0; } int32_t parcel_r_int32(struct parcel_t *p) { int32_t ret; ret = *((int32_t *) (p->data + p->offset)); p->offset += sizeof(int32_t); return ret; } int parcel_w_int32(struct parcel_t *p, int32_t val) { for(;;) { printf("parcel_w_int32(%d): offset = %d, cap = %d, size = %d\n", val, p->offset, p->capacity, p->size); if(p->offset + sizeof(int32_t) < p->capacity) { // There's enough space *((int32_t *) (p->data + p->offset)) = val; p->offset += sizeof(int32_t); p->size += sizeof(int32_t); break; } else { // Grow data and retry if(parcel_grow(p, sizeof(int32_t)) == -1) { return -1; } } } return 0; } int parcel_w_string(struct parcel_t *p, char *str) { char16_t *s16; size_t s16_len; size_t len; if(str == NULL) { parcel_w_int32(p, -1); return 0; } s16 = strdup8to16(str, &s16_len); if(parcel_w_int32(p, s16_len) == -1) { return -1; } len = (s16_len + 1) * sizeof(char16_t); for(;;) { size_t padded = PAD_SIZE(len); printf("parcel_w_string(\"%s\"): offset %d, cap %d, size %d\n", str, p->offset, p->capacity, p->size); if(p->offset + len < p->capacity) { // There's enough space memcpy(p->data + p->offset, s16, s16_len * sizeof(char16_t)); *((char16_t *) (p->data + p->offset + len)) = 0; p->offset += padded; p->size += padded; if (padded != len) { printf("Writing %ld bytes, padded to %ld\n", len, padded); #if BYTE_ORDER == BIG_ENDIAN static const uint32_t mask[4] = { 0x00000000, 0xffffff00, 0xffff0000, 0xff000000 }; #endif #if BYTE_ORDER == LITTLE_ENDIAN static const uint32_t mask[4] = { 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff }; #endif //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len], // *reinterpret_cast<void**>(data+padded-4)); *((uint32_t*)(p->data+p->offset+padded-4)) &= mask[padded-len]; } break; } else { // Grow data and retry if(parcel_grow(p, padded) == -1) { free(s16); return -1; } } } free(s16); return 0; } char *parcel_r_string(struct parcel_t *p) { char *ret; int len = parcel_r_int32(p); printf("parcel_r_string: len = %d\n", len); ret = strndup16to8((char16_t *) (p->data + p->offset), len); p->offset += PAD_SIZE((len + 1) * sizeof(char16_t)); return ret; } size_t parcel_data_avail(struct parcel_t *p) { return (p->size - p->offset); } /* Received SMS - we get a hex string representation of the data. Roughly, the layout of the data is: 1 byte - length of SMS center information 1 byte - the format of the number (91 is the standard) (length above - 1) bytes - the number, nibble-swapped and padded with an f if needed 1 byte - properties of the message, generally we can ignore this 1 byte - length of sender number (in digits, not bytes) variable bytes - sender number, nibble-swapped and padded if needed 1 byte - protocol identifier - can ignore this probably 1 byte - data coding scheme - again can hopefully be ignored 7 bytes - timestamp, again nibble-swapped: y, m, d, h, m, s, timezone * timezone is in units of +15 min vs. GMT. If most sig. bit is 1, value is in units of -15 min vs. GMT. 1 byte - length of message in characters (NOT in bytes) rest of bytes - message. if ASCII 7-bit, compacted to save space through an encoding mechanism. For more information see http://www.dreamfabric.com/sms/ or GSM 03.38 */ struct recvd_sms { char *src_num; char *service_center; char *msg; char *timestamp; }; char gsm_to_ascii(char gsm); int decode_sms(char *hexstr, struct recvd_sms *sms); void acknowledge_sms(int fd); void send_sms(int fd, char *smsc_pdu, char *pdu); void usage(char *name); void loop_for_data(int fd); /* SMS-related functions */ char gsm_to_ascii(char gsm) { switch(gsm) { case '\0': return '@'; } } char *hexify(char *bytes, size_t len) { char *hexarray[256]; int i, j; char *ret; for(i = 0; i < 256; i++) { hexarray[i] = (char *) malloc(3 * sizeof(char)); snprintf(hexarray[i], 3, "%02x", i); } ret = (char *) malloc((len * 2 + 1) * sizeof(char)); for(i = 0, j = 0; i < len; i++, j += 2) { ret[j] = hexarray[(unsigned char) bytes[i]][0]; ret[j + 1] = hexarray[(unsigned char) bytes[i]][1]; } ret[j] = '\0'; return ret; } int decode_sms(char *hexstr, struct recvd_sms *sms) { int smsc_len, src_len, curpos, msg_len; char *endptr; char **bytes; char *service_center, *src_num, *timestamp, *msg; int len, i, j, oldbits, numoldbits; char *msgbytes; /* first, split the string up into hex representations of the bytes-- this makes things much easier overall */ len = strlen(hexstr); if(len % 2 != 0) { fprintf(stderr, "malformed hex string passed to decode_sms\n"); return -1; } bytes = (char **) malloc((len / 2) * sizeof(char *)); for(i = 0; i < len / 2; i++) { bytes[i] = (char *) malloc(3 * sizeof(char)); bytes[i][0] = hexstr[i * 2]; bytes[i][1] = hexstr[i * 2 + 1]; bytes[i][2] = '\0'; } // decode the service center number smsc_len = strtol(bytes[0], &endptr, 16); if(strcmp(bytes[1], "91")) { fprintf(stderr, "unsupported number format for sender: %s", bytes[1]); } service_center = (char *) malloc((smsc_len) * sizeof(char)); service_center[0] = '\0'; for(i = 2, j = 0; i < smsc_len + 1; i++, j += 2) { // number is nibble-swapped service_center[j] = bytes[i][1]; if(bytes[i][0] == 'f') { // num may be padded with 'f' at end service_center[j + 1] = '\0'; } else { service_center[j + 1] = bytes[i][0]; } } service_center[j] = '\0'; curpos = i; sms->service_center = service_center; // next, decode the sender's number src_len = strtol(bytes[curpos + 1], NULL, 16); src_num = (char *) malloc((src_len + 1) * sizeof(char)); // convert src_len from # of digits to # of bytes src_len = (src_len % 2 == 0) ? src_len : src_len + 1; src_len = src_len / 2; if(strcmp(bytes[curpos + 2], "91")) { fprintf(stderr, "unsupported number format for sender: %s", bytes[curpos + 2]); } for(i = curpos + 3, j = 0; i < curpos + 3 + src_len; i++, j += 2) { // number is nibble-swapped src_num[j] = bytes[i][1]; if(bytes[i][0] == 'f') { // num may be padded with 'f' at end src_num[j + 1] = '\0'; } else { src_num[j + 1] = bytes[i][0]; } } src_num[j] = '\0'; sms->src_num = src_num; curpos = i; // Timestamp timestamp = (char *) malloc(9 * sizeof(char)); for(i = curpos + 2, j = 0; i < curpos + 9; i++, j += 2) { // number is nibble-swapped timestamp[j] = bytes[i][1]; timestamp[j + 1] = bytes[i][0]; } curpos = i; timestamp[j] = '\0'; sms->timestamp = timestamp; // Message msg = (char *) malloc(strtol(bytes[curpos], NULL, 16) * sizeof(char)); msg_len = len / 2 - (curpos + 1); msgbytes = (char *) malloc((msg_len) * sizeof(char)); for(i = curpos + 1, j = 0; i < len / 2, j < msg_len; i++, j++) { msgbytes[j] = strtol(bytes[i], NULL, 16); } // convert message to 8-bit ASCII oldbits = 0; numoldbits = 0; for(i = 0, j = 0; i < msg_len; i++, j++) { int numbits = (i % 7) + 1; int newbits; newbits = msgbytes[i] >> (8 - numbits); newbits &= (1 << numbits) - 1; msgbytes[i] = msgbytes[i] & ((1 << (8 - numbits)) - 1); msgbytes[i] = msgbytes[i] << numoldbits; msg[j] = msgbytes[i] | oldbits; // GSM alphabet is different than ASCII alphabet msg[j] = gsm_to_ascii(msg[j]); if(numbits == 7) { msg[j + 1] = newbits; j++; newbits = 0; numbits = 0; } oldbits = newbits; numoldbits = numbits; } msg[j] = '\0'; sms->msg = msg; // cleanup for(i = 0; i < len / 2; i++) { free(bytes[i]); } free(bytes); free(msgbytes); return 0; } char *encode_sms(char *destnum, char *msg) { int i, j, actual_dest_len, enc_msg_len, ret_len; char dest_len[3]; char *dest; char *enc_msg, *final_msg, *ret; // dest_len is the hex representation of the length of the phone # snprintf(dest_len, 3, "%02x", strlen(destnum)); actual_dest_len = (strlen(destnum) % 2 == 0) ? strlen(destnum) : strlen(destnum) + 1; dest = (char *) malloc((actual_dest_len + 1) * sizeof(char)); for(i = 0; i < actual_dest_len; i += 2) { if(destnum[i + 1] != '\0') { dest[i] = destnum[i + 1]; } else { dest[i] = 'f'; } dest[i + 1] = destnum[i]; } dest[i] = '\0'; printf("dest = %s\n", dest); enc_msg_len = strlen(msg) - (strlen(msg) / 8); enc_msg = (char *) malloc((enc_msg_len + 1) * sizeof(char)); for(i = 0, j = 0; i < strlen(msg); i++, j++) { int numbits = (i + 1) % 8; char bits; if(numbits == 0) { j--; continue; } bits = msg[i + 1] & ((1 << numbits) - 1); enc_msg[j] = msg[i] >> numbits - 1; printf("once shifted by %d: %hhx\n", numbits, enc_msg[j]); enc_msg[j] = enc_msg[j] | (bits << (8 - numbits)); printf("bits << (8 - numbits) %hhx\n", bits << (8 - numbits)); printf("%hhx\n", enc_msg[j]); fflush(stdout); } final_msg = hexify(enc_msg, enc_msg_len); ret_len = 14 + strlen(dest) + strlen(final_msg); ret = (char *) malloc((ret_len + 1) * sizeof(char)); // FIXME: too much of the sent msg is hardcoded snprintf(ret, ret_len + 1, "0120%s91%s0000%02x%s", dest_len, dest, strlen(msg), final_msg); printf("%s\n", ret); free(enc_msg); free(final_msg); free(dest); return ret; } /* functions that actually belong here */ void usage(char *name) { printf("%s command [arguments]\n", name); printf("Commands:\n"); printf("a: activate data network\n"); printf("d <number>: dial a number\n"); printf("t <number> <msg>: send an SMS message\n"); } void interpret_sol_response(struct parcel_t *p, int fd) { int seq, error, i; seq = parcel_r_int32(p); error = parcel_r_int32(p); printf("solicited: seq = %d error = %d\n", seq, error); printf("%d bytes left\n", parcel_data_avail(p)); if(seq == 0) { if(!parcel_data_avail(p)) return; int numstr; numstr = parcel_r_int32(p); printf("numstr = %d\n", numstr); for(i = 0; i < numstr; i++) { printf("%s\n", parcel_r_string(p)); } } } void interpret_unsol_response(struct parcel_t *p, int fd) { int resp_type; resp_type = parcel_r_int32(p); printf("unsolicited: type = %d, data left = %d\n", resp_type, parcel_data_avail(p)); if(resp_type == RIL_UNSOL_RESPONSE_NEW_SMS) { struct recvd_sms sms; decode_sms(parcel_r_string(p), &sms); printf("Got SMS: %s from %s (service center %s)\n", sms.msg, sms.src_num, sms.service_center); acknowledge_sms(fd); } } void loop_for_data(int fd) { for(;;) { int msglen, readlen, type, i; char *buf; struct parcel_t p; void *pdata; parcel_init(&p); if(read(fd, &msglen, sizeof(msglen)) != sizeof(msglen)) { fprintf(stderr, "EOF while reading parcel length"); } msglen = ntohl(msglen); buf = (char *) malloc(msglen * sizeof(char)); readlen = read(fd, buf, msglen); if(readlen != msglen) { fprintf(stderr, "msglen = %d readlen = %d\n", msglen, readlen); fprintf(stderr, "got too much or not enough data, aborting\n"); return; } for(i = 0; i < readlen; i++) { printf("%02x", buf[i]); } printf("\n"); parcel_grow(&p, msglen); memcpy(p.data, buf, msglen); p.size = msglen; printf("Received %d bytes of data from rild.\n", msglen); type = parcel_r_int32(&p); if(type == RESPONSE_SOLICITED) { interpret_sol_response(&p, fd); } else { interpret_unsol_response(&p, fd); } free(buf); } } void dial(struct parcel_t *p, int fd, char *number) { int pktlen, ret; parcel_w_int32(p, RIL_REQUEST_DIAL); parcel_w_int32(p, 0); parcel_w_string(p, number); parcel_w_int32(p, 0); parcel_w_int32(p, 0); pktlen = htonl(p->size); ret = write(fd, (void *)&pktlen, sizeof(pktlen)); if(ret < 0) perror("write failed"); ret = write(fd, p->data, p->size); if(ret < 0) perror("write failed"); } void activate_net(struct parcel_t *p, int fd) { int pktlen, ret, i; parcel_w_int32(p, RIL_REQUEST_SETUP_DATA_CALL); // request ID parcel_w_int32(p, 0); // seq number (?) parcel_w_int32(p, 7); // undocumented magic. parcel_w_string(p, "1"); // CDMA or GSM. 1 = GSM parcel_w_string(p, "0"); // data profile. 0 = default parcel_w_string(p, "wap.cingular"); // APN name parcel_w_string(p, "WAP@CINGULARGPRS.COM"); // APN user parcel_w_string(p, "cingular1"); // APN passwd parcel_w_string(p, "0"); // auth type. 0 usually for(i = 0; i < p->size; i++) { printf("%02x", p->data[i]); }