PDA VSP update

pull/69/merge
sfeakes 2023-06-24 14:15:52 -05:00
parent 94320139f1
commit 2d0647ab8d
10 changed files with 281 additions and 189 deletions

View File

@ -96,11 +96,12 @@ struct programmingThreadCtrl {
struct aqualinkdata *aq_data;
};
typedef enum pump_type {
PT_UNKNOWN = -1,
EPUMP,
VSPUMP,
VFPUMP
EPUMP, // = ePump AC & Jandy ePUMP
VSPUMP, // = Intelliflo VS
VFPUMP // = Intelliflo VF
} pump_type;

View File

@ -662,6 +662,7 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
}
rtn=true;
} else if (strncasecmp(param + 9, "_pumpType", 9) == 0) {
// This is not documented, as it's prefered for AqualinkD to find the pump type.
pump_detail *pump = getpump(aqdata, num);
if (pump != NULL) {
if ( stristr(value, "Pentair VS") != 0)

View File

@ -1334,7 +1334,7 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg)
float pass_mg_body(struct mg_str *body) {
LOG(NET_LOG,LOG_INFO, "Message body:\n'%.*s'\n", body->len, body->p);
LOG(NET_LOG,LOG_INFO, "Message body:'%.*s'\n", body->len, body->p);
// Quick n dirty pass value from either of below.
// value=1.5&arg2=val2
// {"value":"1.5"}

View File

@ -338,8 +338,7 @@ bool log_freeze_setpoints(struct aqualinkdata *aq_data)
}
bool get_pumpinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx)
bool get_pumpinfo_from_menu_OLD(struct aqualinkdata *aq_data, int menuLineIdx)
{
int rpm = 0;
int watts = 0;
@ -394,14 +393,81 @@ bool get_pumpinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx)
aq_data->pumps[i].pumpType = EPUMP;
LOG(ONET_LOG, LOG_INFO, "OneTouch Pump index %d set PumpType to %d\n", i, aq_data->pumps[i].pumpType);
return true;
}
return true;
}
}
LOG(ONET_LOG, LOG_WARNING, "Did not find AqualinkD config for Pump '%s'\n",_menu[menuLineIdx]);
return false;
}
bool get_pumpinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx, int pump_number)
{
int rpm = 0;
int watts = 0;
int gpm = 0;
char *cidx = NULL;
// valid controlpanel pump numbers are 1,2,3,4
if (pump_number < 1 || pump_number > MAX_PUMPS) {
LOG(ONET_LOG, LOG_WARNING, "Pump number %d for pump '%s' is invalid, ignoring!\n",pump_number,_menu[menuLineIdx]);
return false;
}
if ( (cidx = rsm_charafterstr(_menu[menuLineIdx + 1], "RPM", AQ_MSGLEN)) != NULL ){
rpm = rsm_atoi(cidx);
// Assuming Watts is always next line and GPM (if available) line after
if ( (cidx = rsm_charafterstr(_menu[menuLineIdx + 2], "Watts", AQ_MSGLEN)) != NULL ){
watts = rsm_atoi(cidx);
}
if ( (cidx = rsm_charafterstr(_menu[menuLineIdx + 3], "GPM", AQ_MSGLEN)) != NULL ){
gpm = rsm_atoi(cidx);
}
}
else if (rsm_strcmp(_menu[menuLineIdx + 1], "*** Priming ***") == 0){
rpm = PUMP_PRIMING;
}
else if (rsm_strcmp(_menu[menuLineIdx + 1], "(Offline)") == 0){
rpm = PUMP_OFFLINE;
}
else if (rsm_strcmp(_menu[menuLineIdx + 1], "(Priming Error)") == 0){
rpm = PUMP_ERROR;
}
if (rpm==0 && watts==0 && rpm==0) {
// Didn't get any info, so return.
return false;
}
LOG(ONET_LOG, LOG_DEBUG, "Found Pump information '%s', RPM %d, Watts %d, GPM %d\n", _menu[menuLineIdx], rpm, watts, gpm);
for (int i=0; i < aq_data->num_pumps; i++) {
if (aq_data->pumps[i].pumpIndex == pump_number) {
LOG(ONET_LOG,LOG_INFO, "Pump label: %s Index: %d, Number: %d, RPM: %d, Watts: %d, GPM: %d\n",aq_data->pumps[i].button->name, i ,pump_number,rpm,watts,gpm);
pump_update(aq_data, i);
aq_data->pumps[i].rpm = rpm;
aq_data->pumps[i].watts = watts;
aq_data->pumps[i].gpm = gpm;
if (aq_data->pumps[i].pumpType == PT_UNKNOWN){
if (rsm_strcmp(_menu[menuLineIdx],"Intelliflo VS") == 0)
aq_data->pumps[i].pumpType = VSPUMP;
else if (rsm_strcmp(_menu[menuLineIdx],"Intelliflo VF") == 0)
aq_data->pumps[i].pumpType = VFPUMP;
else if (rsm_strcmp(_menu[menuLineIdx],"Jandy ePUMP") == 0 ||
rsm_strcmp(_menu[menuLineIdx],"ePump AC") == 0)
aq_data->pumps[i].pumpType = EPUMP;
LOG(ONET_LOG, LOG_INFO, "Pump index %d set PumpType to %d\n", i, aq_data->pumps[i].pumpType);
}
return true;
}
}
LOG(ONET_LOG,LOG_WARNING, "PDA Could not find config for Pump %s, Number %d, RPM %d, Watts %d, GPM %d\n",_menu[menuLineIdx],pump_number,rpm,watts,gpm);
return false;
}
/*
Info: OneTouch Menu Line 1 =
Info: OneTouch Menu Line 2 = Chemlink 1
@ -496,16 +562,25 @@ bool get_RS16buttoninfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx)
bool log_qeuiptment_status_VP2(struct aqualinkdata *aq_data)
{
bool rtn = false;
char *cidx = NULL;
int i;
for (i = 0; i < ONETOUCH_LINES; i++)
{
/*
if (rsm_strcmp(_menu[i], "Intelliflo VS") == 0 ||
rsm_strcmp(_menu[i], "Intelliflo VF") == 0 ||
rsm_strcmp(_menu[i], "Jandy ePUMP") == 0 ||
rsm_strcmp(_menu[i], "ePump AC") == 0)
{
rtn = get_pumpinfo_from_menu(aq_data, i);
}*/
if ( (cidx = rsm_charafterstr(_menu[i], "Intelliflo VS", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(_menu[i], "Intelliflo VF", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(_menu[i], "Jandy ePUMP", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(_menu[i], "ePump AC", AQ_MSGLEN)) != NULL)
{
rtn = get_pumpinfo_from_menu(aq_data, i, rsm_atoi(cidx));
} else if (rsm_strcmp(_menu[2],"AQUAPURE") == 0) {
rtn = get_aquapureinfo_from_menu(aq_data, i);
} else if (rsm_strcmp(_menu[i],"Chemlink") == 0) {
@ -529,12 +604,20 @@ bool log_qeuiptment_status(struct aqualinkdata *aq_data)
return log_qeuiptment_status_VP2(aq_data);
bool rtn = false;
char *cidx = NULL;
/*
if (rsm_strcmp(_menu[2],"Intelliflo VS") == 0 ||
rsm_strcmp(_menu[2],"Intelliflo VF") == 0 ||
rsm_strcmp(_menu[2],"Jandy ePUMP") == 0 ||
rsm_strcmp(_menu[2],"ePump AC") == 0) {
rtn = get_pumpinfo_from_menu(aq_data, 2);
} */
if ( (cidx = rsm_charafterstr(_menu[2], "Intelliflo VS", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(_menu[2], "Intelliflo VF", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(_menu[2], "Jandy ePUMP", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(_menu[2], "ePump AC", AQ_MSGLEN)) != NULL)
{
rtn = get_pumpinfo_from_menu(aq_data, 2, rsm_atoi(cidx));
} else if (rsm_strcmp(_menu[2],"AQUAPURE") == 0) {
rtn = get_aquapureinfo_from_menu(aq_data, 2);
} else if (rsm_strcmp(_menu[2],"Chemlink") == 0) {

275
pda.c
View File

@ -158,109 +158,6 @@ void equiptment_update_cycle(int eqID) {
}
void pass_pda_equiptment_status_item_OLD(char *msg)
{
static char *index;
int i;
// EQUIPMENT STATUS
//
// AquaPure 100%
// SALT 25500 PPM
// FILTER PUMP
// POOL HEAT
// SPA HEAT ENA
// EQUIPMENT STATUS
//
// FREEZE PROTECT
// AquaPure 100%
// SALT 25500 PPM
// CHECK AquaPure
// GENERAL FAULT
// FILTER PUMP
// CLEANER
//
// Equipment Status
//
// Intelliflo VS 1
// RPM: 1700
// Watts: 367
//
//
//
//
//
// JANDY ePUMP 1
// RPM: 2520
// WATTS: 856
// Check message for status of device
// Loop through all buttons and match the PDA text.
if ((index = strcasestr(msg, "CHECK AquaPure")) != NULL)
{
LOG(PDA_LOG,LOG_DEBUG, "CHECK AquaPure\n");
}
else if ((index = strcasestr(msg, "FREEZE PROTECT")) != NULL)
{
_aqualink_data->frz_protect_state = ON;
}
else if ((index = strcasestr(msg, MSG_SWG_PCT)) != NULL)
{
changeSWGpercent(_aqualink_data, atoi(index + strlen(MSG_SWG_PCT)));
//_aqualink_data->swg_percent = atoi(index + strlen(MSG_SWG_PCT));
//if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF) {_aqualink_data->ar_swg_status = SWG_STATUS_ON;}
LOG(PDA_LOG,LOG_DEBUG, "AquaPure = %d\n", _aqualink_data->swg_percent);
}
else if ((index = strcasestr(msg, MSG_SWG_PPM)) != NULL)
{
_aqualink_data->swg_ppm = atoi(index + strlen(MSG_SWG_PPM));
//if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF) {_aqualink_data->ar_swg_status = SWG_STATUS_ON;}
LOG(PDA_LOG,LOG_DEBUG, "SALT = %d\n", _aqualink_data->swg_ppm);
}
else if ((index = strcasestr(msg, MSG_PMP_RPM)) != NULL)
{ // Default to pump 0, should check for correct pump
_aqualink_data->pumps[0].rpm = atoi(index + strlen(MSG_PMP_RPM));
LOG(PDA_LOG,LOG_DEBUG, "RPM = %d\n", _aqualink_data->pumps[0].rpm);
}
else if ((index = strcasestr(msg, MSG_PMP_WAT)) != NULL)
{ // Default to pump 0, should check for correct pump
_aqualink_data->pumps[0].watts = atoi(index + strlen(MSG_PMP_WAT));
LOG(PDA_LOG,LOG_DEBUG, "Watts = %d\n", _aqualink_data->pumps[0].watts);
}
else
{
char labelBuff[AQ_MSGLEN + 2];
strncpy(labelBuff, msg, AQ_MSGLEN + 1);
msg = stripwhitespace(labelBuff);
if (strcasecmp(msg, "POOL HEAT ENA") == 0)
{
_aqualink_data->aqbuttons[_aqualink_data->pool_heater_index].led->state = ENABLE;
}
else if (strcasecmp(msg, "SPA HEAT ENA") == 0)
{
_aqualink_data->aqbuttons[_aqualink_data->spa_heater_index].led->state = ENABLE;
}
else
{
for (i = 0; i < _aqualink_data->total_buttons; i++)
{
if (strcasecmp(msg, _aqualink_data->aqbuttons[i].label) == 0)
{
equiptment_update_cycle(i);
LOG(PDA_LOG,LOG_DEBUG, "Status for %s = '%.*s'\n", _aqualink_data->aqbuttons[i].label, AQ_MSGLEN, msg);
// It's on (or delayed) if it's listed here.
if (_aqualink_data->aqbuttons[i].led->state != FLASH)
{
_aqualink_data->aqbuttons[i].led->state = ON;
}
break;
}
}
}
}
}
void process_pda_packet_msg_long_temp(const char *msg)
{
@ -557,70 +454,124 @@ void pda_pump_update(struct aqualinkdata *aq_data, int updated) {
}
}
/*
// Messages from different PDA versions.
PDA Menu Line 0 = Equipment Status
PDA Menu Line 1 =
PDA Menu Line 2 = Intelliflo VS 1
PDA Menu Line 3 = RPM: 1700
PDA Menu Line 4 = Watts: 367
------------
PDA Menu Line 2 = JANDY ePUMP 1
PDA Menu Line 3 = RPM: 2520
PDA Menu Line 4 = WATTS: 856
------------
PDA Menu Line 0 = EQUIPMENT STATUS
PDA Menu Line 1 =
PDA Menu Line 2 =
PDA Menu Line 3 = *** PRIMING ***
PDA Menu Line 4 = WATTS: 1303
------------
PDA Menu Line 4 = WATTS: 1298
------------
PDA Menu Line 0 = Equipment Status
PDA Menu Line 1 =
PDA Menu Line 2 = Intelliflo VS 1
PDA Menu Line 3 = (Offline)
----------
PDA Menu Line 0 = EQUIPMENT STATUS
PDA Menu Line 1 =
PDA Menu Line 2 = JANDY ePUMP 1
PDA Menu Line 3 = RPM: 2520
PDA Menu Line 4 = WATTS: 809
----------
*/
// NSF This is now VERY similar to onetouch function get_pumpinfo_from_menu(), should thinmk about combining in future
void get_pda_pumpinfo_from_menu(int menuLineIdx, int pump_number)
{
int rpm = 0;
int watts = 0;
int gpm = 0;
char *cidx = NULL;
// valid controlpanel pump numbers are 1,2,3,4
if (pump_number < 1 || pump_number > MAX_PUMPS) {
LOG(PDA_LOG, LOG_WARNING, "Pump number %d for pump '%s' is invalid, ignoring!\n",pump_number,pda_m_line(menuLineIdx));
return;
}
if ( (cidx = rsm_charafterstr(pda_m_line(menuLineIdx+1), "RPM", AQ_MSGLEN)) != NULL ){
rpm = rsm_atoi(cidx);
// Assuming Watts is always next line and GPM (if available) line after
if ( (cidx = rsm_charafterstr(pda_m_line(menuLineIdx+2), "Watts", AQ_MSGLEN)) != NULL ){
watts = rsm_atoi(cidx);
}
if ( (cidx = rsm_charafterstr(pda_m_line(menuLineIdx+3), "GPM", AQ_MSGLEN)) != NULL ){
gpm = rsm_atoi(cidx);
}
}
else if (rsm_strcmp(pda_m_line(menuLineIdx+1), "*** Priming ***") == 0){
rpm = PUMP_PRIMING;
}
else if (rsm_strcmp(pda_m_line(menuLineIdx+1), "(Offline)") == 0){
rpm = PUMP_OFFLINE;
}
else if (rsm_strcmp(pda_m_line(menuLineIdx+1), "(Priming Error)") == 0){
rpm = PUMP_ERROR;
}
if (rpm==0 && watts==0 && rpm==0) {
// Didn't get any info, so return.
return;
}
LOG(PDA_LOG, LOG_DEBUG, "Found Pump information '%s', RPM %d, Watts %d, GPM %d\n", pda_m_line(menuLineIdx), rpm, watts, gpm);
for (int i=0; i < _aqualink_data->num_pumps; i++) {
if (_aqualink_data->pumps[i].pumpIndex == pump_number) {
LOG(PDA_LOG,LOG_DEBUG, "Pump label: %s Index: %d, Number: %d, RPM: %d, Watts: %d, GPM: %d\n",_aqualink_data->pumps[i].button->name, i ,pump_number,rpm,watts,gpm);
pda_pump_update(_aqualink_data, i);
_aqualink_data->pumps[i].rpm = rpm;
_aqualink_data->pumps[i].watts = watts;
_aqualink_data->pumps[i].gpm = gpm;
if (_aqualink_data->pumps[i].pumpType == PT_UNKNOWN){
if (rsm_strcmp(pda_m_line(menuLineIdx),"Intelliflo VS") == 0)
_aqualink_data->pumps[i].pumpType = VSPUMP;
else if (rsm_strcmp(pda_m_line(menuLineIdx),"Intelliflo VF") == 0)
_aqualink_data->pumps[i].pumpType = VFPUMP;
else if (rsm_strcmp(pda_m_line(menuLineIdx),"Jandy ePUMP") == 0 ||
rsm_strcmp(pda_m_line(menuLineIdx),"ePump AC") == 0)
_aqualink_data->pumps[i].pumpType = EPUMP;
LOG(PDA_LOG, LOG_DEBUG, "Pump index %d set PumpType to %d\n", i, _aqualink_data->pumps[i].pumpType);
}
return;
}
}
LOG(PDA_LOG,LOG_WARNING, "PDA Could not find config for Pump %s, Number %d, RPM %d, Watts %d, GPM %d\n",pda_m_line(menuLineIdx),pump_number,rpm,watts,gpm);
}
void log_pump_information() {
int i;
//bool rtn = false;
char *m2_line=pda_m_line(2);
char *m3_line=pda_m_line(3);
char *m4_line=pda_m_line(3);
char *m5_line=pda_m_line(3);
char *cidx = NULL;
if (rsm_strcmp(m2_line,"Intelliflo VS") == 0 ||
rsm_strcmp(m2_line,"Intelliflo VF") == 0 ||
rsm_strcmp(m2_line,"Jandy ePUMP") == 0 ||
rsm_strcmp(m2_line,"ePump AC") == 0) {
//rtn = true;
int rpm = 0;
int watts = 0;
int gpm = 0;
int pump_index = rsm_atoi(&m2_line[14]);
if (pump_index <= 0)
pump_index = rsm_atoi(&m2_line[12]); // Pump inxed is in different position on line ` ePump AC 4`
// RPM displays differently depending on 3 or 4 digit rpm.
if (rsm_strcmp(m3_line,"RPM:") == 0){
rpm = rsm_atoi(&m3_line[10]);
if (rsm_strcmp(m4_line,"Watts:") == 0) {
watts = rsm_atoi(&m4_line[10]);
}
if (rsm_strcmp(m5_line,"GPM:") == 0) {
gpm = rsm_atoi(&m5_line[10]);
}
} else if (rsm_strcmp(m3_line,"*** Priming ***") == 0){
rpm = PUMP_PRIMING;
} else if (rsm_strcmp(m3_line,"(Offline)") == 0){
rpm = PUMP_OFFLINE;
} else if (rsm_strcmp(m3_line,"(Priming Error)") == 0){
rpm = PUMP_ERROR;
for (i = 0; i < PDA_LINES; i++)
{
if ( (cidx = rsm_charafterstr(pda_m_line(i), "Intelliflo VS", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(pda_m_line(i), "Intelliflo VF", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(pda_m_line(i), "Jandy ePUMP", AQ_MSGLEN)) != NULL ||
(cidx = rsm_charafterstr(pda_m_line(i), "ePump AC", AQ_MSGLEN)) != NULL)
{
get_pda_pumpinfo_from_menu(i, rsm_atoi(cidx));
}
LOG(PDA_LOG,LOG_INFO, "PDA Pump %s, Index %d, RPM %d, Watts %d, GPM %d\n",m3_line,pump_index,rpm,watts,gpm);
for (i=0; i < _aqualink_data->num_pumps; i++) {
if (_aqualink_data->pumps[i].pumpIndex == pump_index) {
LOG(PDA_LOG,LOG_INFO, "PDA Pump label: %s Index: %d, ID: %d, RPM: %d, Watts: %d, GPM: %d\n",_aqualink_data->pumps[i].button->name, i ,pump_index,rpm,watts,gpm);
//printf("**** FOUND PUMP %d at index %d *****\n",pump_index,i);
//aq_data->pumps[i].updated = true;
pda_pump_update(_aqualink_data, i);
_aqualink_data->pumps[i].rpm = rpm;
_aqualink_data->pumps[i].watts = watts;
_aqualink_data->pumps[i].gpm = gpm;
if (_aqualink_data->pumps[i].pumpType == PT_UNKNOWN){
if (rsm_strcmp(m2_line,"Intelliflo VS") == 0)
_aqualink_data->pumps[i].pumpType = VSPUMP;
else if (rsm_strcmp(m2_line,"Intelliflo VF") == 0)
_aqualink_data->pumps[i].pumpType = VFPUMP;
else if (rsm_strcmp(m2_line,"Jandy ePUMP") == 0 ||
rsm_strcmp(m2_line,"ePump AC") == 0)
_aqualink_data->pumps[i].pumpType = EPUMP;
}
//printf ("Set Pump Type to %d\n",aq_data->pumps[i].pumpType);
return;
}
}
LOG(PDA_LOG,LOG_ERR, "PDA Could not find config for Pump %s, Index %d, RPM %d, Watts %d, GPM %d\n",m3_line,pump_index,rpm,watts,gpm);
/* // NSF This need to be used in the future and not process_pda_packet_msg_long_equiptment_status()
else if (rsm_strcmp(pda_m_line(i),"AQUAPURE") == 0) {
rtn = get_aquapureinfo_from_menu(aq_data, i);
} else if (rsm_strcmp(pda_m_line(i),"Chemlink") == 0) {
rtn = get_chemlinkinfo_from_menu(aq_data, i);
*/
}
}
void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lineindex, bool reset)
{
LOG(PDA_LOG,LOG_DEBUG, "*** Pass Equiptment msg '%.16s'\n", msg_line);
@ -863,6 +814,10 @@ bool process_pda_packet(unsigned char *packet, int length)
process_pda_packet_msg_long_home(msg);
break;
case PM_EQUIPTMENT_STATUS:
// NSF In the future need to run over this like log_pump_information()
// So move into that function. This way you can get status of devices
// that span over multiple lines (like AQUAPURE).
// Plus tell if a device is not seen in loop, so can turn it off.
process_pda_packet_msg_long_equiptment_status(msg, index, false);
break;
case PM_SET_TEMP:

View File

@ -35,7 +35,7 @@ void print_menu()
int i;
for (i=0; i < PDA_LINES; i++) {
//printf("PDA Line %d = %s\n",i,_menu[i]);
LOG(PDA_LOG,LOG_DEBUG, "PDA Menu Line %d = %s\n",i,_menu[i]);
LOG(PDA_LOG,LOG_INFO, "PDA Menu Line %d = %s\n",i,_menu[i]);
}
if (_hlightindex > -1) {

Binary file not shown.

Binary file not shown.

View File

@ -84,6 +84,35 @@ bool rsm_get_revision(char *dest, const char *src, int src_len)
return true;
}
/*
Find first char after a space in haystack after searching needle.
' RPM: 1234 '
' RPM 1234 '
' RPMcrap 1 '
Search RPM in above should return 1 in all cases.
return NULL is not found
*/
char *rsm_charafterstr(const char *haystack, const char *needle, int length)
{
// Need to make this case insensative
char *sp = rsm_strncasestr(haystack,needle,length);
if(sp == NULL)
return NULL;
sp = sp+strlen(needle);
while(*sp != ' ') {
sp++;
if (sp > haystack+length)
return NULL;
}
return ++sp;
}
/*
Can probably replace this with rsm_strncasestr in all code.
*/
char *rsm_strstr(const char *haystack, const char *needle)
{
char *sp1 = (char *)haystack;
@ -101,35 +130,53 @@ char *rsm_strstr(const char *haystack, const char *needle)
return strcasestr(sp1, sp2);
}
char *rsm_strncasestr(const char *haystack, const char *needle, int length)
{
// NEED TO WRITE THIS MYSELF. Same as below but limit length
return strcasestr(haystack, needle);
}
/*
* Find the first occurrence of find in s, where the search is limited to the
* first slen characters of s.
* Find the first occurrence of needle in haystack, where the search is limited to the
* first slen characters of haystack.
*/
char *rsm_strnstr(const char *s, const char *find, size_t slen)
char *rsm_strnstr(const char *haystack, const char *needle, size_t slen)
{
char c, sc;
size_t len;
if ((c = *find++) != '\0') {
len = strlen(find);
if ((c = *needle++) != '\0') {
len = strlen(needle);
do {
do {
if (slen-- < 1 || (sc = *s++) == '\0')
if (slen-- < 1 || (sc = *haystack++) == '\0')
return (NULL);
} while (sc != c);
if (len > slen)
return (NULL);
} while (strncmp(s, find, len) != 0);
s--;
} while (strncmp(haystack, needle, len) != 0);
haystack--;
}
return ((char *)s);
return ((char *)haystack);
}
/*
* Case insensative version of above (rsm_strnstr)
* Find the first occurrence of needle in haystack, where the search is limited to the
* first slen characters of haystack.
*/
char *rsm_strncasestr(const char *haystack, const char *needle, size_t slen)
{
char c, sc;
size_t len;
if ((c = *needle++) != '\0') {
len = strlen(needle);
do {
do {
if (slen-- < 1 || (sc = *haystack++) == '\0')
return (NULL);
} while ( tolower(sc) != tolower(c));
if (len > slen)
return (NULL);
} while (strncasecmp(haystack, needle, len) != 0);
haystack--;
}
return ((char *)haystack);
}
// Check s2 exists in s1
@ -169,7 +216,7 @@ int rsm_strncmp(const char *haystack, const char *needle, int length)
while(isspace(*ep1)) ep1--;
LOG(AQUA_LOG,LOG_DEBUG, "CHECK haystack SP1='%c' EP1='%c' SP2='%c' '%.*s' for '%s' length=%d\n",*sp1,*ep1,*sp2,(ep1-sp1)+1,sp1,sp2,(ep1-sp1)+1);
//LOG(AQUA_LOG,LOG_DEBUG, "CHECK haystack SP1='%c' EP1='%c' SP2='%c' '%.*s' for '%s' length=%d\n",*sp1,*ep1,*sp2,(ep1-sp1)+1,sp1,sp2,(ep1-sp1)+1);
// Need to write this myself for speed
// Need to check if full length string (no space on end), that the +1 is accurate. MIN should do it
return strncasecmp(sp1, sp2, MIN((ep1-sp1)+1,length));

View File

@ -1,10 +1,15 @@
#ifndef RS_MSG_UTILS_H_
#define RS_MSG_UTILS_H_
bool rsm_get_revision(char *dest, const char *src, int src_len);
char *rsm_charafterstr(const char *haystack, const char *needle, int length);
char *rsm_strstr(const char *haystack, const char *needle);
//char *rsm_strnstr(const char *haystack, const char *needle, int length);
char *rsm_strnstr(const char *s, const char *find, size_t slen);
char *rsm_strncasestr(const char *haystack, const char *needle, int length);
char *rsm_strnstr(const char *haystack, const char *needle, size_t slen);
char *rsm_strncasestr(const char *haystack, const char *needle, size_t length);
int rsm_strncpy(char *dest, const unsigned char *src, int dest_len, int src_len);
int rsm_strcmp(const char *s1, const char *s2);
int rsm_strncmp(const char *haystack, const char *needle, int length);
@ -12,6 +17,6 @@ int rsm_strncpy_nul2sp(char *dest, const unsigned char *src, int dest_len, int s
int rsm_atoi(const char* str);
float rsm_atof(const char* str);
char *rsm_strncpycut(char *dest, const char *src, int dest_len, int src_len);
bool rsm_get_revision(char *dest, const char *src, int src_len);
#endif //RS_MSG_UTILS_H_