Index: src/testcid.c =================================================================== --- src/testcid.c (revision 236) +++ src/testcid.c (working copy) @@ -1,17 +1,295 @@ #include "openzap.h" + +typedef zap_status_t (*zap_fsk_write_sample_t)(int16_t *buf, zap_size_t buflen, void *user_data); + +#define ZAP_FSK_MOD_FACTOR 0x10000 +struct zap_fsk_transmitter { + teletone_dds_state_t dds; + zap_bitstream_t bs; + uint32_t carrier_bits_start; + uint32_t carrier_bits_stop; + uint32_t chan_sieze_bits; + uint32_t bit_factor; + uint32_t bit_accum; + uint32_t sample_counter; + fsk_modem_types_t modem_type; + zap_fsk_data_state_t *fsk_data; + zap_fsk_write_sample_t write_sample_callback; + void *user_data; + int16_t sample_buffer[64]; +}; + + + + +zap_status_t zap_fsk_transmitter_init(zap_fsk_transmitter_t *fsk_trans, + fsk_modem_types_t modem_type, + uint32_t sample_rate, + zap_fsk_data_state_t *fsk_data, + float db_level, + uint32_t carrier_bits_start, + uint32_t carrier_bits_stop, + uint32_t chan_sieze_bits, + zap_fsk_write_sample_t write_sample_callback, + void *user_data) +{ + memset(fsk_trans, 0, sizeof(*fsk_trans)); + fsk_trans->modem_type = modem_type; + teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_space, sample_rate, 0); + teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_mark, sample_rate, 1); + fsk_trans->bit_factor = (fsk_modem_definitions[fsk_trans->modem_type].baud_rate * ZAP_FSK_MOD_FACTOR) / (float)sample_rate; + + fsk_trans->bit_accum = 0; + fsk_trans->fsk_data = fsk_data; + teletone_dds_state_set_tx_level(&fsk_trans->dds, db_level); + zap_bitstream_init(&fsk_trans->bs, fsk_trans->fsk_data->buf, fsk_trans->fsk_data->dlen, ZAP_ENDIAN_BIG, 1); + fsk_trans->carrier_bits_start = carrier_bits_start; + fsk_trans->carrier_bits_stop = carrier_bits_stop; + fsk_trans->chan_sieze_bits = chan_sieze_bits; + fsk_trans->write_sample_callback = write_sample_callback; + fsk_trans->user_data = user_data; + return ZAP_SUCCESS; +} + +zap_size_t zap_fsk_transmitter_generate_bit(zap_fsk_transmitter_t *fsk_trans, int8_t bit, int16_t *buf, zap_size_t buflen) +{ + zap_size_t i; + + for(i = 0 ; i < buflen; i++) { + + fsk_trans->bit_accum += fsk_trans->bit_factor; + if (fsk_trans->bit_accum >= ZAP_FSK_MOD_FACTOR) { + fsk_trans->bit_accum -= (ZAP_FSK_MOD_FACTOR + fsk_trans->bit_factor); + break; + } + + buf[i] = teletone_dds_state_modulate_sample(&fsk_trans->dds, bit); + } + + return i; +} + + +int32_t zap_fsk_transmitter_generate_carrier_bits(zap_fsk_transmitter_t *fsk_trans, uint32_t bits) +{ + uint32_t i = 0; + zap_size_t r = 0; + int bit = 1; + + for (i = 0; i < bits; i++) { + if ((r = zap_fsk_transmitter_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { + fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data); + } else { + break; + } + } + + return i; +} + +void zap_fsk_transmitter_generate_chan_sieze(zap_fsk_transmitter_t *fsk_trans) +{ + uint32_t i = 0; + zap_size_t r = 0; + int bit = 0; + + for (i = 0; i < fsk_trans->chan_sieze_bits; i++) { + if ((r = zap_fsk_transmitter_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { + fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data); + } else { + break; + } + bit = !bit; + } + + +} + + +void zap_fsk_transmitter_send_data(zap_fsk_transmitter_t *fsk_trans) +{ + zap_size_t r = 0; + int8_t bit = 0; + + while((bit = zap_bitstream_get_bit(&fsk_trans->bs)) > -1) { + if ((r = zap_fsk_transmitter_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { + fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data); + } else { + break; + } + } +} + + + + +struct helper { + int fd; +}; + +zap_status_t my_write_sample(int16_t *buf, zap_size_t buflen, void *user_data) +{ + struct helper *foo = (struct helper *) user_data; + write(foo->fd, buf, buflen * 2); +} + + + +#define myrate 8000 +#define each 7 int main(int argc, char *argv[]) { - zap_fsk_data_state_t state = {0}; - int fd; + struct zap_fsk_transmitter fsk_trans; + zap_fsk_data_state_t fsk_data = {0}; + int fd = -1; int16_t buf[160] = {0}; ssize_t len = 0; int type, mlen; char *sp; char str[128] = ""; char fbuf[256]; + uint8_t databuf[1024] = ""; + struct helper foo; + + + if (argc < 2) { + int x; + char *url = "sip:cool@rad.com"; - if (argc < 2 || zap_fsk_demod_init(&state, 8000, fbuf, sizeof(fbuf))) { + if ((fd = open("tone.raw", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { + fprintf(stderr, "File Error!\n", strerror(errno)); + exit(-1); + } + + + zap_fsk_data_init(&fsk_data, databuf, sizeof(databuf)); +#if 1 + zap_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, "06061234", 8); + zap_fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NUM, "5551212", 7); + zap_fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NAME, "Fred Smith", 10); + zap_fsk_data_add_mdmf(&fsk_data, MDMF_ALT_ROUTE, url, strlen(url)); +#else + zap_fsk_data_add_sdmf(&fsk_data, "06061234", "0"); + //zap_fsk_data_add_sdmf(&state, "06061234", "5551212"); +#endif + zap_fsk_data_add_checksum(&fsk_data); + + foo.fd = fd; + + zap_fsk_transmitter_init(&fsk_trans, + FSK_BELL202, + myrate, + &fsk_data, + -14, + 180, + 5, + 300, + my_write_sample, + &foo); + + + zap_fsk_transmitter_generate_chan_sieze(&fsk_trans); + + zap_fsk_transmitter_generate_carrier_bits(&fsk_trans, fsk_trans.carrier_bits_start); + zap_fsk_transmitter_send_data(&fsk_trans); + zap_fsk_transmitter_generate_carrier_bits(&fsk_trans, fsk_trans.carrier_bits_stop); +#if 0 + + + { + int8_t bit; + uint32_t last = 0; + int c = 0; + int16_t sample; + int w = 0, x, z = 0; + int b = 0; + + for(x = 0; x < 300; x++) { + for(w = 0; w < each; w++) { + sample = teletone_dds_state_modulate_sample(&fsk_trans.dds, z); + write(fd, &sample, sizeof(sample)); + } + printf("%d", z); + + z = !z; + + if (++b == 50) { + printf("\n"); + b = 0; + } + } + printf("\n"); + + + for(x = 0; x < 180; x++) { + for(w = 0; w < each; w++) { + sample = teletone_dds_state_modulate_sample(&fsk_trans.dds, 1); + write(fd, &sample, sizeof(sample)); + } + printf("%d", 1); + + if (++b == 50) { + printf("\n"); + b = 0; + } + } + printf("\n"); + + last = fsk_trans.bs.byte_index; + while((bit = zap_bitstream_get_bit(&fsk_trans.bs)) > -1) { + printf("%d", bit); + + for(w = 0; w < each; w++) { + sample = teletone_dds_state_modulate_sample(&fsk_trans.dds, bit); + write(fd, &sample, sizeof(sample)); + } + + if (fsk_trans.bs.byte_index != last) { + last = fsk_trans.bs.byte_index; + printf(" "); + if (++c == 8) { + printf("\n"); + c = 0; + } + + } + } + } + +#endif + +#if 0 + printf("d=[%d] b=[%d]\n", fsk_data.dlen, fsk_data.blen); + for (x = 0; x < fsk_data.dlen; x++) { + if ( databuf[x] < 48 || databuf[x] > 127) { + printf("[%d]", databuf[x]); + } else { + printf("%c", databuf[x]); + } + } + printf("\n"); + + fsk_data.ppos = 0; + fsk_data.checksum = fsk_data.buf[fsk_data.dlen]; + + while(zap_fsk_data_parse(&fsk_data, &type, &sp, &mlen) == ZAP_SUCCESS) { + zap_copy_string(str, sp, mlen+1); + *(str+mlen) = '\0'; + zap_clean_string(str); + printf("TYPE %d (%s) LEN %d VAL [%s]\n", type, zap_mdmf_type2str(type), mlen, str); + } + +#endif + printf("\n\n"); + if (fd > -1) { + close (fd); + } + + return 0; + } + + if (zap_fsk_demod_init(&fsk_data, myrate, fbuf, sizeof(fbuf))) { printf("wtf\n"); return 0; } @@ -22,19 +300,19 @@ } while((len = read(fd, buf, sizeof(buf))) > 0) { - if (zap_fsk_demod_feed(&state, buf, len / 2) != ZAP_SUCCESS) { + if (zap_fsk_demod_feed(&fsk_data, buf, len / 2) != ZAP_SUCCESS) { break; } } - while(zap_fsk_data_parse(&state, &type, &sp, &mlen) == ZAP_SUCCESS) { + while(zap_fsk_data_parse(&fsk_data, &type, &sp, &mlen) == ZAP_SUCCESS) { zap_copy_string(str, sp, mlen+1); *(str+mlen) = '\0'; zap_clean_string(str); printf("TYPE %d (%s) LEN %d VAL [%s]\n", type, zap_mdmf_type2str(type), mlen, str); } - zap_fsk_demod_destroy(&state); + zap_fsk_demod_destroy(&fsk_data); close(fd); } Index: src/include/openzap.h =================================================================== --- src/include/openzap.h (revision 236) +++ src/include/openzap.h (working copy) @@ -241,6 +241,20 @@ return s; } + +struct zap_bitstream { + uint8_t *data; + uint32_t datalen; + uint32_t byte_index; + uint8_t bit_index; + int8_t endian; + uint8_t top; + uint8_t bot; + uint8_t ss; + uint8_t ssv; +}; + + struct zap_caller_data { char cid_name[80]; char cid_num[80]; @@ -364,11 +378,17 @@ zio_span_next_event_t next_event; }; + + + zap_status_t zap_fsk_data_parse(zap_fsk_data_state_t *state, zap_size_t *type, char **data, zap_size_t *len); zap_status_t zap_fsk_demod_feed(zap_fsk_data_state_t *state, int16_t *data, size_t samples); zap_status_t zap_fsk_demod_destroy(zap_fsk_data_state_t *state); int zap_fsk_demod_init(zap_fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize); - +zap_status_t zap_fsk_data_init(zap_fsk_data_state_t *state, uint8_t *data, uint32_t datalen); +zap_status_t zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_mdmf_type_t type, int8_t *data, uint32_t datalen); +zap_status_t zap_fsk_data_add_checksum(zap_fsk_data_state_t *state); +zap_status_t zap_fsk_data_add_sdmf(zap_fsk_data_state_t *state, char *date, char *number); zap_status_t zap_channel_outgoing_call(zap_channel_t *zchan); void zap_channel_rotate_tokens(zap_channel_t *zchan); void zap_channel_clear_detected_tones(zap_channel_t *zchan); @@ -403,7 +423,7 @@ void zap_global_set_logger(zap_logger_t logger); void zap_global_set_default_logger(int level); uint32_t zap_separate_string(char *buf, char delim, char **array, int arraylen); -void print_bits(uint8_t *b, int bl, char *buf, int blen, int e); +void print_bits(uint8_t *b, int bl, char *buf, int blen, int e, int ss); ZIO_CODEC_FUNCTION(zio_slin2ulaw); ZIO_CODEC_FUNCTION(zio_ulaw2slin); ZIO_CODEC_FUNCTION(zio_slin2alaw); Index: src/include/zap_types.h =================================================================== --- src/include/zap_types.h (revision 236) +++ src/include/zap_types.h (working copy) @@ -64,6 +64,11 @@ typedef uint64_t zap_time_t; typedef enum { + ZAP_ENDIAN_BIG = 1, + ZAP_ENDIAN_LITTLE = -1 +} zap_endian_t; + +typedef enum { ZAP_CID_TYPE_SDMF = 0x04, ZAP_CID_TYPE_MDMF = 0x80 } zap_cid_type_t; @@ -75,9 +80,10 @@ MDMF_NO_NUM = 4, MDMF_PHONE_NAME = 7, MDMF_NO_NAME = 8, - MDMF_INVALID = 9 + MDMF_ALT_ROUTE = 9, + MDMF_INVALID = 10 } zap_mdmf_type_t; -#define MDMF_STRINGS "X", "DATETIME", "PHONE_NUM", "DDN", "NO_NUM", "X", "X", "PHONE_NAME", "NO_NAME", "INVALID" +#define MDMF_STRINGS "X", "DATETIME", "PHONE_NUM", "DDN", "NO_NUM", "X", "X", "PHONE_NAME", "NO_NAME", "ALT_ROUTE", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_mdmf_type, zap_mdmf_type2str, zap_mdmf_type_t) struct zap_fsk_data_state { @@ -371,6 +377,9 @@ typedef struct hashtable_itr zap_hash_itr_t; typedef struct key zap_hash_key_t; typedef struct value zap_hash_val_t; +typedef struct zap_bitstream zap_bitstream_t; +typedef struct zap_fsk_transmitter zap_fsk_transmitter_t; + #endif /* For Emacs: Index: src/include/fsk.h =================================================================== --- src/include/fsk.h (revision 236) +++ src/include/fsk.h (working copy) @@ -107,5 +107,7 @@ void dsp_fsk_sample(dsp_fsk_handle_t *handle, double normalized_sample); +extern fsk_modem_definition_t fsk_modem_definitions[]; + #endif Index: src/zap_isdn.c =================================================================== --- src/zap_isdn.c (revision 236) +++ src/zap_isdn.c (working copy) @@ -89,7 +89,7 @@ zap_size_t len = (zap_size_t) mlen; #ifdef IODEBUG char bb[4096] = ""; - print_bits(msg, (int)len, bb, sizeof(bb), 1); + print_bits(msg, (int)len, bb, sizeof(bb), 1, 0); zap_log(ZAP_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)len, LINE, bb); #endif @@ -140,7 +140,7 @@ if (zap_channel_read(data->dchan, buf, &len) == ZAP_SUCCESS) { #ifdef IODEBUG char bb[4096] = ""; - print_bits(buf, (int)len, bb, sizeof(bb), 1); + print_bits(buf, (int)len, bb, sizeof(bb), 1, 0); zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)len, LINE, bb); #endif Index: src/zap_io.c =================================================================== --- src/zap_io.c (revision 236) +++ src/zap_io.c (working copy) @@ -1832,34 +1832,95 @@ return argc; } -void print_bits(uint8_t *b, int bl, char *buf, int blen, int e) +void zap_bitstream_init(zap_bitstream_t *bsp, uint8_t *data, uint32_t datalen, zap_endian_t endian, int ss) { - int i,j = 0, k, l = 0; + memset(bsp, 0, sizeof(*bsp)); + bsp->data = data; + bsp->datalen = datalen; + bsp->endian = endian; + bsp->ss = ss; + + if (endian < 0) { + bsp->top = bsp->bit_index = 7; + bsp->bot = 0; + } else { + bsp->top = bsp->bit_index = 0; + bsp->bot = 7; + } - if (blen < (bl * 10) + 2) { - return; +} + +int8_t zap_bitstream_get_bit(zap_bitstream_t *bsp) +{ + int8_t bit = -1; + + + if (bsp->byte_index >= bsp->datalen) { + goto done; } - for (k = 0 ; k < bl; k++) { - buf[j++] = '['; - if (e) { - for(i = 7; i >= 0; i--) { - buf[j++] = ((b[k] & (1 << i)) ? '1' : '0'); - } - } else { - for(i = 0; i < 8; i++) { - buf[j++] = ((b[k] & (1 << i)) ? '1' : '0'); - } + if (bsp->ss) { + if (!bsp->ssv) { + bsp->ssv = 1; + return 0; + } else if (bsp->ssv == 2) { + bsp->byte_index++; + bsp->ssv = 0; + return 1; } - buf[j++] = ']'; - buf[j++] = ' '; - if (++l == 6) { - buf[j++] = '\n'; - l = 0; + } + + + + + bit = (bsp->data[bsp->byte_index] >> (bsp->bit_index)) & 1; + + if (bsp->bit_index == bsp->bot) { + bsp->bit_index = bsp->top; + if (bsp->ss) { + bsp->ssv = 2; + goto done; + } + + if (++bsp->byte_index > bsp->datalen) { + bit = -1; + goto done; } + + } else { + bsp->bit_index += bsp->endian; } + + + done: + return bit; +} + + +void print_bits(uint8_t *b, int bl, char *buf, int blen, zap_endian_t e, int ss) +{ + zap_bitstream_t bs; + int j = 0, c = 0; + int8_t bit; + uint32_t last; + + if (blen < (bl * 10) + 2) { + return; + } - buf[j++] = '\0'; + zap_bitstream_init(&bs, b, bl, e, ss); + last = bs.byte_index; + while((bit = zap_bitstream_get_bit(&bs)) > -1) { + buf[j++] = bit ? '1' : '0'; + if (bs.byte_index != last) { + buf[j++] = ' '; + last = bs.byte_index; + if (++c == 8) { + buf[j++] = '\n'; + c = 0; + } + } + } } Index: src/fsk.c =================================================================== --- src/fsk.c (revision 236) +++ src/fsk.c (working copy) @@ -46,7 +46,7 @@ #define M_PI 3.14159265358979323846 #endif -static fsk_modem_definition_t fsk_modem_definitions[] = +fsk_modem_definition_t fsk_modem_definitions[] = { { /* FSK_V23_FORWARD_MODE1 */ 1700, 1300, 600 }, { /* FSK_V23_FORWARD_MODE2 */ 2100, 1300, 1200 }, Index: src/zap_callerid.c =================================================================== --- src/zap_callerid.c (revision 236) +++ src/zap_callerid.c (working copy) @@ -36,6 +36,62 @@ } } +zap_status_t zap_fsk_data_init(zap_fsk_data_state_t *state, uint8_t *data, uint32_t datalen) +{ + memset(state, 0, sizeof(*state)); + state->buf = data; + state->bufsize = datalen; + state->bpos = 2; + + return ZAP_SUCCESS; +} + +zap_status_t zap_fsk_data_add_sdmf(zap_fsk_data_state_t *state, char *date, char *number) +{ + size_t dlen = strlen(date); + size_t nlen = strlen(number); + + state->buf[0] = ZAP_CID_TYPE_SDMF; + memcpy(&state->buf[state->bpos], date, dlen); + state->bpos += dlen; + memcpy(&state->buf[state->bpos], number, nlen); + state->bpos += nlen; + + return ZAP_SUCCESS; +} + +zap_status_t zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_mdmf_type_t type, int8_t *data, uint32_t datalen) +{ + state->buf[0] = ZAP_CID_TYPE_MDMF; + state->buf[state->bpos++] = type; + state->buf[state->bpos++] = datalen; + memcpy(&state->buf[state->bpos], data, datalen); + state->bpos += datalen; + return ZAP_SUCCESS; +} + + +zap_status_t zap_fsk_data_add_checksum(zap_fsk_data_state_t *state) +{ + uint32_t i; + uint8_t check = 0; + + state->buf[1] = state->bpos - 2; + + for (i = 0; i < state->bpos; i++) { + check += state->buf[i]; + } + + state->checksum = state->buf[state->bpos] = 256 - check; + state->bpos++; + + state->dlen = state->bpos; + state->blen = state->buf[1]; + + return ZAP_SUCCESS; +} + + zap_status_t zap_fsk_data_parse(zap_fsk_data_state_t *state, zap_size_t *type, char **data, zap_size_t *len) { @@ -54,6 +110,7 @@ } state->checksum = sum % 256; state->ppos = 2; + if (state->buf[0] != ZAP_CID_TYPE_MDMF && state->buf[0] != ZAP_CID_TYPE_SDMF) { state->checksum = -1; } Index: Makefile =================================================================== --- Makefile (revision 236) +++ Makefile (working copy) @@ -113,7 +113,7 @@ $(CC) $(INCS) -L. $(SRC)/testapp.c -o testapp -lopenzap -lm -lpthread testcid: $(SRC)/testcid.c $(MYLIB) - $(CC) $(INCS) -L. $(SRC)/testcid.c -o testcid -lopenzap -lm -lpthread + $(CC) $(INCS) -L. -g -ggdb $(SRC)/testcid.c -o testcid -lopenzap -lm -lpthread testtones: $(SRC)/testtones.c $(MYLIB) $(CC) $(INCS) -L. $(SRC)/testtones.c -o testtones -lopenzap -lm -lpthread