long dbPutSpecial(DBADDR *paddr,int pass) { long int (*pspecial)()=NULL; struct rset *prset; dbCommon *precord = paddr->precord; long status=0; long special=paddr->special; prset = dbGetRset(paddr); if(special<100) { /*global processing*/ if((special==SPC_NOMOD) && (pass==0)) { status = S_db_noMod; recGblDbaddrError(status,paddr,"dbPut"); return(status); }else if(special==SPC_SCAN){ if(pass==0) scanDelete(precord); else scanAdd(precord); }else if((special==SPC_AS) && (pass==1)) { if(spcAsCallback) (*spcAsCallback)(precord); } }else { if( prset && (pspecial = (prset->special))) { status=(*pspecial)(paddr,pass); if(status) return(status); } else if(pass==0){ recGblRecSupError(S_db_noSupport,paddr,"dbPut", "special"); return(S_db_noSupport); } } return(0); }
/** * Start scan WiFi networks available * @param async run in async mode * @param show_hidden show hidden networks * @return Number of discovered networks */ int8_t WiFiScanClass::scanNetworks(bool async, bool show_hidden) { if(WiFiScanClass::_scanStarted) { return WIFI_SCAN_RUNNING; } WiFiScanClass::_scanAsync = async; WiFi.enableSTA(true); scanDelete(); wifi_scan_config_t config; config.ssid = 0; config.bssid = 0; config.channel = 0; config.show_hidden = show_hidden; if(esp_wifi_scan_start(&config, WiFiScanClass::_scanAsync) == ESP_OK) { WiFiScanClass::_scanComplete = false; WiFiScanClass::_scanStarted = true; if(WiFiScanClass::_scanAsync) { return WIFI_SCAN_RUNNING; } while(!(WiFiScanClass::_scanComplete)) { delay(10); } return WiFiScanClass::_scanCount; } else { return WIFI_SCAN_FAILED; } }
int8_t ESP8266WiFiClass::scanNetworks(bool async) { if(ESP8266WiFiClass::_scanStarted) { return WIFI_SCAN_RUNNING; } ESP8266WiFiClass::_scanAsync = async; if(_useApMode) { // turn on AP+STA mode mode(WIFI_AP_STA); } else { // turn on STA mode mode(WIFI_STA); } int status = wifi_station_get_connect_status(); if (status != STATION_GOT_IP && status != STATION_IDLE) { disconnect(); } scanDelete(); struct scan_config config; config.ssid = 0; config.bssid = 0; config.channel = 0; config.show_hidden = 0; if(wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiClass::_scanDone))) { ESP8266WiFiClass::_scanComplete = false; ESP8266WiFiClass::_scanStarted = true; if(ESP8266WiFiClass::_scanAsync) { delay(0); // time for the OS to trigger the scan return WIFI_SCAN_RUNNING; } esp_yield(); return ESP8266WiFiClass::_scanCount; } else { return WIFI_SCAN_FAILD; } }
/** * Start scan WiFi networks available * @param async run in async mode * @param show_hidden show hidden networks * @return Number of discovered networks */ int8_t WiFiScanClass::scanNetworks(bool async, bool show_hidden, bool passive, uint32_t max_ms_per_chan) { if(WiFiScanClass::_scanStarted) { return WIFI_SCAN_RUNNING; } WiFiScanClass::_scanAsync = async; WiFi.enableSTA(true); scanDelete(); wifi_scan_config_t config; config.ssid = 0; config.bssid = 0; config.channel = 0; config.show_hidden = show_hidden; if(passive){ config.scan_type = WIFI_SCAN_TYPE_PASSIVE; config.scan_time.passive = max_ms_per_chan; } else { config.scan_type = WIFI_SCAN_TYPE_ACTIVE; config.scan_time.active.min = 100; config.scan_time.active.max = max_ms_per_chan; } if(esp_wifi_scan_start(&config, false) == ESP_OK) { WiFiScanClass::_scanComplete = false; WiFiScanClass::_scanStarted = true; if(WiFiScanClass::_scanAsync) { return WIFI_SCAN_RUNNING; } while(!(WiFiScanClass::_scanComplete)) { delay(10); } return WiFiScanClass::_scanCount; } else { return WIFI_SCAN_FAILED; } }
static long dbPutFieldLink(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { dbLinkInfo link_info; DBADDR *pdbaddr = NULL; dbCommon *precord = paddr->precord; dbCommon *lockrecs[2]; dbLocker locker; dbFldDes *pfldDes = paddr->pfldDes; long special = paddr->special; struct link *plink = (struct link *)paddr->pfield; const char *pstring = (const char *)pbuffer; struct dsxt *old_dsxt = NULL; struct dset *new_dset = NULL; struct dsxt *new_dsxt = NULL; devSup *new_devsup = NULL; long status; int isDevLink; short scan; STATIC_ASSERT(DBLOCKER_NALLOC>=2); switch (dbrType) { case DBR_CHAR: case DBR_UCHAR: if (pstring[nRequest - 1] != '\0') return S_db_badDbrtype; break; case DBR_STRING: break; default: return S_db_badDbrtype; } status = dbParseLink(pstring, pfldDes->field_type, &link_info); if (status) return status; if (link_info.ltype == PV_LINK && (link_info.modifiers & (pvlOptCA | pvlOptCP | pvlOptCPP)) == 0) { DBADDR tempaddr; if (dbNameToAddr(link_info.target, &tempaddr)==0) { /* This will become a DB link. */ pdbaddr = malloc(sizeof(*pdbaddr)); if (!pdbaddr) { status = S_db_noMemory; goto cleanup; } *pdbaddr = tempaddr; /* struct copy */ } } isDevLink = ellCount(&precord->rdes->devList) > 0 && pfldDes->isDevLink; memset(&locker, 0, sizeof(locker)); lockrecs[0] = precord; lockrecs[1] = pdbaddr ? pdbaddr->precord : NULL; dbLockerPrepare(&locker, lockrecs, 2); dbScanLockMany(&locker); scan = precord->scan; if (isDevLink) { new_devsup = dbDTYPtoDevSup(precord->rdes, precord->dtyp); if (new_devsup) { new_dset = new_devsup->pdset; new_dsxt = new_devsup->pdsxt; } } if (dbCanSetLink(plink, &link_info, new_devsup)) { /* link type mis-match prevents assignment */ status = S_dbLib_badField; goto unlock; } if (isDevLink) { if (precord->dset) { devSup *old_devsup = dbDSETtoDevSup(precord->rdes, precord->dset); if (old_devsup) old_dsxt = old_devsup->pdsxt; } if (new_dsxt == NULL || new_dsxt->add_record == NULL || (precord->dset && old_dsxt == NULL) || (old_dsxt && old_dsxt->del_record == NULL)) { status = S_db_noSupport; goto unlock; } if (scan == menuScanI_O_Intr) { scanDelete(precord); precord->scan = menuScanPassive; } if (old_dsxt) { status = old_dsxt->del_record(precord); if (status) goto restoreScan; } } switch (plink->type) { /* Old link type */ case DB_LINK: case CA_LINK: case CONSTANT: dbRemoveLink(&locker, plink); /* link type becomes PV_LINK */ break; case PV_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto restoreScan; } break; } if (special) status = dbPutSpecial(paddr, 0); if (!status) status = dbSetLink(plink, &link_info, new_devsup); if (!status && special) status = dbPutSpecial(paddr, 1); if (status) { if (isDevLink) { precord->dset = NULL; precord->pact = TRUE; } goto postScanEvent; } if (isDevLink) { precord->dpvt = NULL; precord->dset = new_dset; precord->pact = FALSE; status = new_dsxt->add_record(precord); if (status) { precord->dset = NULL; precord->pact = TRUE; goto postScanEvent; } } switch (plink->type) { /* New link type */ case PV_LINK: case CONSTANT: dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr); break; case DB_LINK: case CA_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto postScanEvent; } break; } db_post_events(precord, plink, DBE_VALUE | DBE_LOG); restoreScan: if (isDevLink && scan == menuScanI_O_Intr) { /* undo scanDelete() */ precord->scan = scan; scanAdd(precord); } postScanEvent: if (scan != precord->scan) db_post_events(precord, &precord->scan, DBE_VALUE | DBE_LOG); unlock: dbScanUnlockMany(&locker); dbLockerFinalize(&locker); cleanup: free(link_info.target); return status; }
static long dbPutFieldLink(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { dbCommon *precord = paddr->precord; dbFldDes *pfldDes = paddr->pfldDes; long special = paddr->special; DBLINK *plink = (DBLINK *)paddr->pfield; const char *pstring = (const char *)pbuffer; DBENTRY dbEntry; DBADDR dbaddr; struct dsxt *old_dsxt = NULL; struct dset *new_dset = NULL; struct dsxt *new_dsxt = NULL; long status; int isDevLink; short scan; switch (dbrType) { case DBR_CHAR: case DBR_UCHAR: if (pstring[nRequest - 1] != '\0') return S_db_badDbrtype; break; case DBR_STRING: break; default: return S_db_badDbrtype; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (status) goto finish; isDevLink = ellCount(&precord->rdes->devList) > 0 && (strcmp(pfldDes->name, "INP") == 0 || strcmp(pfldDes->name, "OUT") == 0); dbLockSetGblLock(); dbLockSetRecordLock(precord); scan = precord->scan; if (isDevLink) { devSup *pdevSup = dbDTYPtoDevSup(precord->rdes, precord->dtyp); if (pdevSup) { new_dset = pdevSup->pdset; new_dsxt = pdevSup->pdsxt; } if (precord->dset) { pdevSup = dbDSETtoDevSup(precord->rdes, precord->dset); if (pdevSup) old_dsxt = pdevSup->pdsxt; } if (new_dsxt == NULL || new_dsxt->add_record == NULL || (precord->dset && old_dsxt == NULL) || (old_dsxt && old_dsxt->del_record == NULL)) { status = S_db_noSupport; goto unlock; } if (scan == menuScanI_O_Intr) { scanDelete(precord); precord->scan = menuScanPassive; } if (old_dsxt) { status = old_dsxt->del_record(precord); if (status) goto restoreScan; } } switch (plink->type) { /* Old link type */ case DB_LINK: free(plink->value.pv_link.pvt); plink->value.pv_link.pvt = 0; plink->type = PV_LINK; plink->value.pv_link.getCvt = 0; plink->value.pv_link.pvlMask = 0; plink->value.pv_link.lastGetdbrType = 0; dbLockSetSplit(precord); break; case CA_LINK: dbCaRemoveLink(plink); plink->type = PV_LINK; plink->value.pv_link.getCvt = 0; plink->value.pv_link.pvlMask = 0; plink->value.pv_link.lastGetdbrType = 0; break; case CONSTANT: break; /* do nothing */ case PV_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto restoreScan; } break; } if (special) status = dbPutSpecial(paddr, 0); if (!status) status = dbPutString(&dbEntry, pstring); if (!status && special) status = dbPutSpecial(paddr, 1); if (status) { if (isDevLink) { precord->dset = NULL; precord->pact = TRUE; } goto postScanEvent; } if (isDevLink) { precord->dpvt = NULL; precord->dset = new_dset; precord->pact = FALSE; status = new_dsxt->add_record(precord); if (status) { precord->dset = NULL; precord->pact = TRUE; goto postScanEvent; } } switch (plink->type) { /* New link type */ case PV_LINK: if (plink == &precord->tsel) recGblTSELwasModified(plink); plink->value.pv_link.precord = precord; if (!(plink->value.pv_link.pvlMask & (pvlOptCA|pvlOptCP|pvlOptCPP)) && (dbNameToAddr(plink->value.pv_link.pvname, &dbaddr) == 0)) { /* It's a DB link */ DBADDR *pdbAddr; plink->type = DB_LINK; pdbAddr = dbMalloc(sizeof(struct dbAddr)); *pdbAddr = dbaddr; /* NB: structure copy */; plink->value.pv_link.pvt = pdbAddr; dbLockSetRecordLock(pdbAddr->precord); dbLockSetMerge(precord, pdbAddr->precord); } else { /* Make it a CA link */ char *pperiod; plink->type = CA_LINK; if (pfldDes->field_type == DBF_INLINK) { plink->value.pv_link.pvlMask |= pvlOptInpNative; } dbCaAddLink(plink); if (pfldDes->field_type == DBF_FWDLINK) { pperiod = strrchr(plink->value.pv_link.pvname, '.'); if (pperiod && strstr(pperiod, "PROC")) plink->value.pv_link.pvlMask |= pvlOptFWD; } } break; case CONSTANT: break; case DB_LINK: case CA_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto postScanEvent; } break; } db_post_events(precord, plink, DBE_VALUE | DBE_LOG); restoreScan: if (isDevLink && scan == menuScanI_O_Intr) { /* undo scanDelete() */ precord->scan = scan; scanAdd(precord); } postScanEvent: if (scan != precord->scan) db_post_events(precord, &precord->scan, DBE_VALUE|DBE_LOG); unlock: dbLockSetGblUnlock(); finish: dbFinishEntry(&dbEntry); return status; }