Datum plvstr_betwn_i(PG_FUNCTION_ARGS) { text *string_in = PG_GETARG_TEXT_P(0); int start_in = PG_GETARG_INT32(1); int end_in = PG_GETARG_INT32(2); bool inclusive = PG_GETARG_BOOL(3); if ((start_in < 0 && end_in > 0) || (start_in > 0 && end_in < 0) || (start_in > end_in)) PARAMETER_ERROR("Wrong positions."); if (start_in < 0) { int v_len = ora_mb_strlen1(string_in); start_in = v_len + start_in + 1; end_in = v_len + start_in + 1; } if (!inclusive) { start_in += 1; end_in -= 1; if (start_in > end_in) PG_RETURN_TEXT_P(cstring_to_text("")); } PG_RETURN_TEXT_P(ora_substr_text(string_in, start_in, end_in - start_in + 1)); }
int xbee_remoteAT_frame_assemble(String mac_addr,String ntwk_addr,char option,String cmd, char para) { if(!mac_addr || !ntwk_addr || !cmd) PARAMETER_ERROR("xbee_remoteAT_frame_assemble"); outbuf[0] = ZIGBEE_START_DELIMITER; outbuf[1] = 00; //outbuf[2] = len%256; outbuf[3] = 0x17; //frame type outbuf[4] = 0x01; //frame id int i; for(i=0; i<8; i++) outbuf[5+i] = mac_addr[i]; outbuf[13] = ntwk_addr[0]; outbuf[14] = ntwk_addr[1]; outbuf[15] = option; outbuf[16] = cmd[0]; outbuf[17] = cmd[1]; if(para=='Q') { //query, no para outbuf[2] = 15; outbuf[18] = xbee_set_checksum(&outbuf[3],15); return 19; } else { outbuf[2] = 15; outbuf[18] = para; outbuf[19] = xbee_set_checksum(&outbuf[3],16); return 20; } }
Byte xbee_set_checksum(String xbee_data, int len) { if(!xbee_data) PARAMETER_ERROR("xbee_set_chechsum"); int sum = 0; int i; for(i=0; i<len; i++) { //can't use strlen() because the data may contain 0x00 sum += xbee_data[i]; sum = (sum>255)?(sum-256):sum; } return (Byte)(0xFF-sum); }
int ora_instr(text *txt, text *pattern, int start, int nth) { int len_txt, len_pat; const char *str_txt, *str_pat; int beg, end, i, dx; if (nth <= 0) PARAMETER_ERROR("Four parameter isn't positive."); /* Forward for multibyte strings */ if (pg_database_encoding_max_length() > 1) return ora_instr_mb(txt, pattern, start, nth); str_txt = VARDATA_ANY(txt); len_txt = VARSIZE_ANY_EXHDR(txt); str_pat = VARDATA_ANY(pattern); len_pat = VARSIZE_ANY_EXHDR(pattern); if (start > 0) { dx = 1; beg = start - 1; end = len_txt - len_pat + 1; if (beg >= end) return 0; /* out of range */ } else { dx = -1; beg = Min(len_txt + start, len_txt - len_pat); end = -1; if (beg <= end) return 0; /* out of range */ } for (i = beg; i != end; i += dx) { if (memcmp(str_txt + i, str_pat, len_pat) == 0) { if (--nth == 0) return i + 1; } } return 0; }
int xbee_txReq_data_assemble(String mac_addr,String ntwk_addr,char radius,char option,String RFData,int len,String* retStr) { if(!mac_addr || !ntwk_addr || !RFData || !retStr) PARAMETER_ERROR("xbee_txReq_data_assemble"); //int len = strlen(RFData); String str = malloc(len+15); str[0] = 0x10; str[1] = 0x01; str[2] = 0; strncat(str,mac_addr,8); strncat(str,ntwk_addr,2); str[12] = radius; str[13] = option; str[14] = 0; strncat(str,RFData,len); *retStr = str; return len+14; }
int tty_serial_write(int fds, String buf, int len) { if(fds<0 || !buf) PARAMETER_ERROR("tty_serial_write"); ssize_t ret; int bytes = 0; while (len!=0 && (ret=write(fds,buf,len))!=0) { if(ret==-1) { if(errno==EINTR) continue; perror("read the starting 3 bytes"); return 0; } len -= ret; buf += ret; bytes+=ret; } memset(buf,0,MAX_FRAME_SIZE); return bytes; }
int xbee_localAT_frame_assemble(String cmd, char para) { if(!cmd) PARAMETER_ERROR("xbee_localAT_frame_assemble"); outbuf[0] = ZIGBEE_START_DELIMITER; outbuf[1] = 00; //outbuf[2] = len%256; outbuf[3] = 0x08; //frame type outbuf[4] = 0x01; //frame id outbuf[5] = cmd[0]; outbuf[6] = cmd[1]; if(para=='Q') { //query, no para outbuf[2] = 4; outbuf[7] = xbee_set_checksum(&outbuf[3],4); return 8; } else { outbuf[2] = 5; outbuf[7] = para; outbuf[8] = xbee_set_checksum(&outbuf[3],5); return 9; } }
static bool is_kind(char c, int kind) { switch (kind) { case 1: return c == ' '; case 2: return '0' <= c && c <= '9'; case 3: return c == '\''; case 4: return (32 <= c && c <= 47) || (58 <= c && c <= 64) || (91 <= c && c <= 96) || (123 <= c && c <= 126); case 5: return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); default: PARAMETER_ERROR("Second parametr isn't in enum {1,2,3,4,5}"); return false; } }
mqtt_ptr_t xbee_data_read(String xbee_data,int len) { if(!xbee_data) PARAMETER_ERROR("xbee_data_read"); Byte frame_type = xbee_data[0]; printf("received frame type: %d\n",(int)frame_type); mqtt_ptr_t mydata = NULL; switch(frame_type) { case 0x90 : //received an RF packet mydata = xbee_rx_data_read(xbee_data,len); break; case 0x91 : //explicit rx indicator mydata = xbee_exrx_data_read(xbee_data,len); break; case 0x97 : //remote AT response case 0x8A : //modem status //printf(""); case 0x8B : //transmit status default: break; } return mydata; }
int xbee_txReq_frame_assemble(String mac_addr,String ntwk_addr,char radius,char option,String RFData,int len) { if(!mac_addr || !ntwk_addr || !RFData) PARAMETER_ERROR("xbee_txReq_frame_assemble"); //int len = strlen(RFData) + 14; //frame length field, not the total length if(outbuf[0]) memset(outbuf,0,MAX_FRAME_SIZE); len += 14; outbuf[0] = ZIGBEE_START_DELIMITER; outbuf[1] = len/256; outbuf[2] = len%256; outbuf[3] = 0x10; //frame type outbuf[4] = 0x01; //frame id int i; for(i=0; i<8; i++) outbuf[5+i] = mac_addr[i]; outbuf[13] = ntwk_addr[0]; outbuf[14] = ntwk_addr[1]; outbuf[15] = radius; outbuf[16] = option; for(i=0; i<len-14; i++) outbuf[17+i] = RFData[i]; outbuf[len+3] = xbee_set_checksum(&outbuf[3],len); outbuf[len+4] = 0; return len+4; //return total length }
int xbee_frame_descape(String buf, int len) { if(!buf) PARAMETER_ERROR("xbee_frame_descape"); int i,j, leng=len; char esc[MAX_FRAME_SIZE]; esc[0] = 0; //save the number of escape characters for(i=3; i<len-1; i++) { //just escape the data section if(buf[i]==0x7D) { esc[0]++; esc[esc[0]] = i; leng--; } } //insert algorithm esc[esc[0]+1] = len; for(i=1;i<=esc[0];i++) { for(j=esc[i]+1;j<esc[i+1];j++) { buf[j-i] = buf[j]; } buf[esc[i]+1-i] ^= 0x20; } return leng; }
Datum plvstr_rvrs(PG_FUNCTION_ARGS) { text *str; int start; int end; int len; int i; int new_len; text *result; char *data; char *sizes = NULL; int *positions = NULL; bool mb_encode; if (PG_ARGISNULL(0)) PG_RETURN_NULL(); str = PG_GETARG_TEXT_PP(0); mb_encode = pg_database_encoding_max_length() > 1; if (!mb_encode) len = VARSIZE_ANY_EXHDR(str); else len = ora_mb_strlen(str, &sizes, &positions); start = PG_ARGISNULL(1) ? 1 : PG_GETARG_INT32(1); end = PG_ARGISNULL(2) ? (start < 0 ? -len : len) : PG_GETARG_INT32(2); if ((start > end && start > 0) || (start < end && start < 0)) PARAMETER_ERROR("Second parameter is bigger than third."); if (start < 0) { int new_start, new_end; new_start = len + start + 1; new_end = len + end + 1; start = new_end; end = new_start; } start = start != 0 ? start : 1; end = end < len ? end : len; new_len = end - start + 1; new_len = new_len >= 0 ? new_len : 0; if (mb_encode) { int max_size; int cur_size; char *p; int j; int fz_size; fz_size = VARSIZE_ANY_EXHDR(str); if ((max_size = (new_len*pg_database_encoding_max_length())) > fz_size) result = palloc(fz_size + VARHDRSZ); else result = palloc(max_size + VARHDRSZ); data = (char*) VARDATA(result); cur_size = 0; p = VARDATA_ANY(str); for (i = end - 1; i>= start - 1; i--) { for (j=0; j<sizes[i]; j++) *data++ = *(p+positions[i]+j); cur_size += sizes[i]; } SET_VARSIZE(result, cur_size + VARHDRSZ); } else { char *p = VARDATA_ANY(str); result = palloc(new_len + VARHDRSZ); data = (char*) VARDATA(result); SET_VARSIZE(result, new_len + VARHDRSZ); for (i = end - 1; i >= start - 1; i--) *data++ = p[i]; } PG_RETURN_TEXT_P(result); }
//read one total frame and load the data section(except for the start three bytes) into buf //and return the length of it(including the checksum bit) int tty_serial_read(int fds, String tbuf) { if(fds<0 || !tbuf) PARAMETER_ERROR("tty_serial_read"); if(tbuf[0]) memset(tbuf,0,MAX_FRAME_SIZE); while(tbuf[0]!='~') { if(read(fds,tbuf,1)<0) { perror("reading ttyUSB0"); sleep(2); } } tbuf++; //point to the new position ssize_t ret; int i,bytes=1,leng = 2; //bytes:bytes already read, length: bytes to read while (leng!=0 && (ret=read(fds,tbuf,leng))!=0) { if(ret==-1) { if(errno==EINTR) continue; perror("read the starting 3 bytes"); //no data available in non-blocking mode or other errors sleep(2); return -1; } leng -= ret; tbuf += ret; } bytes += 2; leng = inbuf[1]*256 + inbuf[2] +1; //including the checksum bit, be careful to use inbuf cauze tbuf is moving!! printf("received data section length including the checksum: %d\n",leng); //continue reading the followint bytes of length leng and check escape int nr_escapes = leng; do { leng = nr_escapes; while (leng!=0 && (ret=read(fds,tbuf,leng))!=0) { if(ret==-1) { if(errno==EINTR) continue; perror("read the data section error"); sleep(1); return -1; } leng -= ret; tbuf += ret; } bytes += nr_escapes; int i, leng = nr_escapes; nr_escapes = 0; for(i=bytes-leng;i<bytes;i++) { //check the newly read bytes if(inbuf[i]==0x7D) { printf("the byte after escape: %d %d\n",i, inbuf[i+1]); //int c = tbuf[1+i]; //if(c==0x7E || c==0x11 || c==0x13 || c==0x7D) { nr_escapes++; } } } while(nr_escapes); #ifndef DEBUG leng = bytes; String fbuf = inbuf; int logfds = open("./esclog.txt", O_CREAT | O_RDWR | O_APPEND); while (leng!=0 && (ret=write(logfds,fbuf,leng))!=0) { if(ret==-1) { if(errno==EINTR) continue; perror("wrinting to log file"); } leng -= ret; fbuf += ret; } if(close(logfds)==-1) perror("close esclog file"); #endif //descape and check checksum bytes = xbee_frame_descape(inbuf,bytes); Byte cs = xbee_set_checksum(&inbuf[3],bytes-3); if(cs!=0) { if(cs == 3 && inbuf[38] == 10) { printf("%s\n","line return ..."); //memset(inbuf,0,bytes); } else { printf("%s %d %d\n","checksum error...",cs,inbuf[38]); return 0; } } else { printf("%s total bytes after descape: %d seq: %d\n","checksum perfect!",bytes,inbuf[38]); } #ifndef DEBUG leng = bytes; fbuf = inbuf; int dlogfds = open("./esclog.txt", O_CREAT | O_RDWR | O_APPEND); while (leng!=0 && (ret=write(dlogfds,fbuf,leng))!=0) { if(ret==-1) { if(errno==EINTR) continue; perror("wrinting to dlog file"); } leng -= ret; fbuf += ret; } if(close(dlogfds)==-1) perror("close desclog file"); #endif return bytes; }
//read Explicit Rx_indicator(0x91) data section, return the desired data structure pointer mqtt_ptr_t xbee_exrx_data_read(String xbee_data,int len) { if(!xbee_data) PARAMETER_ERROR("xbee_exrx_data_read"); mqtt_ptr_t mqtt = malloc(sizeof(*mqtt)); mqtt->ts = time(NULL); String mac_addr = str_get_between_index(xbee_data,len,1,8); int i,j; uint64_t sum = 0; for(i=0; i<8; i++) { Byte c = (mac_addr[i]<0) ? (mac_addr[i]+256):mac_addr[i]; uint64_t pow = (uint64_t)c; for(j=0;j<7-i;j++){ //pow*power(256,7-i) pow *= 256; } sum += pow; } mqtt->addr = sum; free(mac_addr); //String wframe = str_get_between_index(xbee_data,len,12,len-2); //excluding the checksum //String s = wframe_get_data_between_del(wframe,len-13,1,2,'#'); //begin from the start index of RF data for(i=18; i++; i<len) { if(xbee_data[i]=='#') { j = i; break; } } if(j+3>len-1) { printf("%s\n","# not found, invalid waspmote frame..."); return NULL; } mqtt->len = len-j-3; mqtt->msg = (void*)str_get_between_index(xbee_data,len,j+3,len-1); printf("%s\n",(char*)(mqtt->msg)); //int bytes = xbee_mqtt_wframe_assenble(mqtt); //tty_serial_write(tty_fds,outbuf,bytes); return mqtt; /* String mac_addr = str_get_between_index(xbee_data,2,9); String wframe = str_get_between_index(xbee_data,18,len-2); //FIRST GET THE PAYLOAD STRING and then convert it to map format String payload_str = NULL; map_ptr_t payload_map = NULL; int fields = *(wframe+4); //the fifth char, expressed as 0x03(char with asc value 3), so no need to convert (from asc) to number payload_str = wframe_get_data_between_del(wframe,len-19,1,2,'#'); payload_map = str_to_map(payload_str,'#',':'); printf("%d %d %d\n",wframe[0],wframe[1],fields); data_ptr_t mydata = (data_ptr_t)malloc(sizeof(Data)); mydata->address = mac_addr; mydata->payload = payload_map; free(payload_str); free(wframe); return mydata; */ }
//read ZigBee Receive Packet(0x90) data section excluding the checksum, return the desired data structure pointer mqtt_ptr_t xbee_rx_data_read(String xbee_data,int len) { if(!xbee_data) PARAMETER_ERROR("xbee_rx_data_read"); mqtt_ptr_t mqtt = malloc(sizeof(*mqtt)); mqtt->ts = time(NULL); String mac_addr = str_get_between_index(xbee_data,len,1,8); int i,j; uint64_t sum = 0; for(i=0; i<8; i++) { Byte c = (mac_addr[i]<0) ? (mac_addr[i]+256):mac_addr[i]; uint64_t pow = (uint64_t)c; for(j=0;j<7-i;j++){ //pow*power(256,7-i) pow *= 256; } sum += pow; } mqtt->addr = sum; //String wframe = str_get_between_index(xbee_data,len,12,len-2); //excluding the checksum //String s = wframe_get_data_between_del(wframe,len-13,1,2,'#'); //begin from the start index of RF data for(i=12; i++; i<len) { if(xbee_data[i]=='#') { j = i; break; } } if(j+3>len-1) { printf("%s\n","# not found, invalid waspmote frame..."); return NULL; } mqtt->len = len-j-3; mqtt->msg = (void*)str_get_between_index(xbee_data,len,j+3,len-1); String data = malloc(mqtt->len); data = memcpy(data,mqtt->msg,mqtt->len); printf("%s %ld\n",data,mqtt->addr); //int bytes = xbee_mqtt_wframe_assenble(mqtt); //tty_serial_write(tty_fds,outbuf,bytes); String ntw_addr = str_get_between_index(xbee_data,len,9,10); //String RFData = (char*)mqtt->msg; //int leng = mqtt->len; //char ntw_addr[2] = {0xFF,0xFE}; String RFData = "hello"; int leng = 5; int bytes = xbee_txReq_frame_assemble(mac_addr,ntw_addr,0,0,RFData,leng); int logfds = open("./wresclog.txt", O_CREAT | O_RDWR | O_APPEND); int ret = 0; leng = bytes; String fbuf = outbuf; while (leng>0 && (ret=write(logfds,fbuf,leng))!=0) { if(ret==-1) { if(errno==EINTR) continue; perror("wrinting to log file"); } leng -= ret; fbuf += ret; } if(close(logfds)==-1) perror("close log file"); bytes = tty_serial_write(tty_fds,outbuf,bytes); printf("write %d bytes... %d\n",bytes,RFData[0]); //free(mac_addr); //free(ntw_addr); //free(RFData); return mqtt; //FIRST GET THE PAYLOAD STRING and then convert it to map format /*String payload_str = NULL; map_ptr_t payload_map = NULL; int fields = *(wframe+4); //the fifth char, expressed as 0x03(char with asc value 3), so no need to convert (from asc) to number payload_str = wframe_get_data_between_del(wframe,4,fields+4,'#'); payload_map = str_to_map(payload_str,'#',':'); printf("%c %c %d\n",wframe[0],wframe[1],fields); data_ptr_t mydata = (data_ptr_t)malloc(sizeof(Data)); mydata->address = mac_addr; mydata->payload = payload_map; free(payload_str); free(wframe); return mydata; */ }
//read ZigBee Receive Packet(0x90) data section excluding the checksum, return the desired data structure pointer mqtt_ptr_t xbee_rx_data_read(String xbee_data,int len) { if(!xbee_data) PARAMETER_ERROR("xbee_rx_data_read"); mqtt_ptr_t mqtt = malloc(sizeof(*mqtt)); mqtt->ts = time(NULL); String mac_addr = str_get_between_index(xbee_data,len,1,8); int i,j; uint64_t sum = 0; for(i=0; i<8; i++) { Byte c = (mac_addr[i]<0) ? (mac_addr[i]+256):mac_addr[i]; uint64_t pow = (uint64_t)c; for(j=0;j<7-i;j++){ //pow*power(256,7-i) pow *= 256; } sum += pow; } mqtt->addr = sum; //String wframe = str_get_between_index(xbee_data,len,12,len-2); //excluding the checksum //String s = wframe_get_data_between_del(wframe,len-13,1,2,'#'); //begin from the start index of RF data for(i=12; i++; i<len) { if(xbee_data[i]=='#') { j = i; break; } } if(j+3>len-1) { printf("%s\n","# not found, invalid waspmote frame..."); return NULL; } mqtt->len = len-j-3; mqtt->msg = (void*)str_get_between_index(xbee_data,len,j+3,len-1); String data = malloc(mqtt->len); data = memcpy(data,mqtt->msg,mqtt->len); printf("%s %ld\n",data,mqtt->addr); //int bytes = xbee_mqtt_wframe_assenble(mqtt); //tty_serial_write(tty_fds,outbuf,bytes); String ntw_addr = str_get_between_index(xbee_data,len,9,10); //String RFData = (char*)mqtt->msg; //int leng = mqtt->len; //char ntw_addr[2] = {0xFF,0xFE}; String RFData = "hello"; int leng = 5; int bytes = xbee_txReq_frame_assemble(mac_addr,ntw_addr,0,0,RFData,leng); int logfds = open("./wresclog.txt", O_CREAT | O_RDWR | O_APPEND); int ret = 0; leng = bytes; String fbuf = outbuf; while (leng>0 && (ret=write(logfds,fbuf,leng))!=0) { if(ret==-1) { if(errno==EINTR) continue; perror("wrinting to log file"); } leng -= ret; fbuf += ret; } if(close(logfds)==-1) perror("close log file"); bytes = tty_serial_write(tty_fds,outbuf,bytes); printf("write %d bytes... %d\n",bytes,RFData[0]); return mqtt; }