static void ICACHE_FLASH_ATTR flowTimerCb(void) { // 1 second if (flowOverridden) { ETS_GPIO_INTR_DISABLE(); flowCount = 0; ETS_GPIO_INTR_ENABLE(); } else { ETS_GPIO_INTR_DISABLE(); oneSecFlowCount = flowCount; flowCount = 0; ETS_GPIO_INTR_ENABLE(); } flowSetAverage(oneSecFlowCount); if (flowAverage == 0) { // Use average to deal with any timing issues when demand oscillates INFOP("!"); secondsNotFlowingCount++; } else { INFOP(">"); secondsNotFlowingCount = 0; } flowCountPerReading += oneSecFlowCount; if (oneSecFlowCount < flowMin) { flowMin = oneSecFlowCount; } if (oneSecFlowCount > flowMax) { flowMax = oneSecFlowCount; } calcFlows(); }
/** * List the hashes supported by each repo implementation. * * NOTE: I don't have a way to verify that the list is complete or verify * NOTE: what it should contain, so I just print the list. */ void MyFn(list_hashes)(SG_context * pCtx) { SG_repo * pRepo = NULL; SG_vhash * pvh_vtables = NULL; SG_vhash * pvh_HashMethods = NULL; SG_uint32 k, count_vtables; VERIFY_ERR_CHECK( SG_repo__query_implementation(pCtx,NULL, SG_REPO__QUESTION__VHASH__LIST_REPO_IMPLEMENTATIONS, NULL,NULL,NULL,0, &pvh_vtables) ); VERIFY_ERR_CHECK( SG_vhash__count(pCtx,pvh_vtables,&count_vtables) ); for (k=0; k<count_vtables; k++) { const char * pszKey_vtable_k; SG_uint32 j, count_HashMethods; VERIFY_ERR_CHECK( SG_vhash__get_nth_pair(pCtx,pvh_vtables,k,&pszKey_vtable_k,NULL) ); INFOP("vtable",("Repo Implementation[%d]: [%s]",k,pszKey_vtable_k)); VERIFY_ERR_CHECK( SG_repo__alloc(pCtx,&pRepo,pszKey_vtable_k) ); VERIFY_ERR_CHECK( SG_repo__query_implementation(pCtx,pRepo, SG_REPO__QUESTION__VHASH__LIST_HASH_METHODS, NULL,NULL,NULL,0, &pvh_HashMethods) ); VERIFY_ERR_CHECK( SG_vhash__count(pCtx,pvh_HashMethods,&count_HashMethods) ); for (j=0; j<count_HashMethods; j++) { const char * pszKey_HashMethod_j; const SG_variant * pVariant; SG_int64 i64; SG_uint32 strlen_Hash_j; VERIFY_ERR_CHECK( SG_vhash__get_nth_pair(pCtx,pvh_HashMethods,j,&pszKey_HashMethod_j,&pVariant) ); VERIFY_ERR_CHECK( SG_variant__get__int64(pCtx,pVariant,&i64) ); strlen_Hash_j = (SG_uint32)i64; INFOP("vtable.hash_method",("Repo [%s] Hash [%s] Length [%d]",pszKey_vtable_k,pszKey_HashMethod_j,strlen_Hash_j)); } SG_VHASH_NULLFREE(pCtx, pvh_HashMethods); SG_REPO_NULLFREE(pCtx, pRepo); } fail: SG_VHASH_NULLFREE(pCtx, pvh_HashMethods); SG_REPO_NULLFREE(pCtx, pRepo); SG_VHASH_NULLFREE(pCtx, pvh_vtables); }
void ICACHE_FLASH_ATTR publishMapping(void) { if (mqttIsConnected()) { char *topic = (char *) os_zalloc(50); char *data = (char *) os_zalloc(500); int idx; if (topic == NULL || data == NULL) { ERRORP("malloc err %s/%s\n", topic, data); startFlash(-1, 50, 50); // fast return; } os_sprintf(topic, "/Raw/%10s/mapping", sysCfg.device_id); os_sprintf(data, "["); for (idx=0; idx<MAP_TEMP_SIZE; idx++) { if (idx != 0) os_sprintf(data + os_strlen(data), ", "); os_sprintf(data + os_strlen(data), "{\"map\":%d,\"name\":\"%s\", \"sensorID\": \"%s\"}", sysCfg.mapping[idx], sysCfg.mappingName[idx], unmappedSensorID(idx)); } os_sprintf(data + os_strlen(data), "]"); if (!MQTT_Publish(mqttClient, topic, data, os_strlen(data), 0, true)) printMQTTstate(); INFOP("%s=>%s\n", topic, data); checkMinHeap(); os_free(topic); os_free(data); } }
void ICACHE_FLASH_ATTR smartConfig_done(sc_status status, void *pdata) { switch (status) { case SC_STATUS_WAIT: os_printf("SC_STATUS_WAIT\n"); break; case SC_STATUS_FIND_CHANNEL: os_printf("SC_STATUS_FIND_CHANNEL\n"); break; case SC_STATUS_GETTING_SSID_PSWD: os_printf("SC_STATUS_GETTING_SSID_PSWD\n"); break; case SC_STATUS_LINK: os_printf("SC_STATUS_LINK\n"); struct station_config *sta_conf = pdata; wifi_station_set_config(sta_conf); INFOP("Connected to %s (%s) %d", sta_conf->ssid, sta_conf->password, sta_conf->bssid_set); strcpy(sysCfg.sta_ssid, sta_conf->ssid); strcpy(sysCfg.sta_pwd, sta_conf->password); wifi_station_disconnect(); wifi_station_connect(); break; case SC_STATUS_LINK_OVER: os_printf("SC_STATUS_LINK_OVER\n"); smartconfig_stop(); checkSmartConfig(SC_HAS_STOPPED); sysCfg.sta_ssid; break; } }
void ICACHE_FLASH_ATTR publishAllTemperatures(void) { struct Temperature *t; int idx; if (mqttIsConnected()) { char *topic = (char*) os_malloc(100), *data = (char*) os_malloc(100); if (topic == NULL || data == NULL) { ERRORP("malloc err %s/%s\n", topic, data); startFlash(-1, 50, 50); // fast return; } for (idx = 0; idx < MAX_TEMPERATURE_SENSOR; idx++) { if (getUnmappedTemperature(idx, &t)) { os_sprintf(topic, (const char*) "/Raw/%s/%s/info", sysCfg.device_id, t->address); os_sprintf(data, (const char*) "{ \"Type\":\"Temp\", \"Value\":\"%c%d.%02d\"}", t->sign, t->val, t->fract); if (!MQTT_Publish(mqttClient, topic, data, os_strlen(data), 0, 0)) printMQTTstate(); INFOP("%s=>%s\n", topic, data); } } checkMinHeap(); os_free(topic); os_free(data); } }
void MyFn(create_zero_byte_blob)(SG_context* pCtx, SG_repo* pRepo) { struct z { const char * pszHashMethod; const char * pszTrivialHash; }; struct z az[] = { { "SHA1/160", "da39a3ee5e6b4b0d3255bfef95601890afd80709" }, { "SHA2/256", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, { "SHA2/384", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" }, { "SHA2/512", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" }, }; char* pszidHidBlob1 = NULL; char * pbuf1 = NULL; char * pbuf2 = NULL; SG_uint64 lenBuf2; SG_repo_tx_handle* pTx = NULL; SG_uint32 lenBuf1 = 0; char * pszHashMethod = NULL; SG_uint32 k, kLimit; pbuf1 = (char *)SG_calloc(1,lenBuf1+1); VERIFY_ERR_CHECK_DISCARD( SG_repo__begin_tx(pCtx, pRepo, &pTx) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__store_blob_from_memory(pCtx, pRepo,pTx,NULL,SG_FALSE,(SG_byte *)pbuf1,lenBuf1,&pszidHidBlob1) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__commit_tx(pCtx, pRepo, &pTx) ); INFOP("create_zero_byte_blob",("Created blob [%s]",(pszidHidBlob1))); ////////////////////////////////////////////////////////////////// // fetch blob into a new buffer and verify that it matches. VERIFY_ERR_CHECK_DISCARD( SG_repo__fetch_blob_into_memory(pCtx, pRepo,pszidHidBlob1,(SG_byte **)&pbuf2,&lenBuf2) ); VERIFY_COND("create_zero_byte_blob(fetch blob)",(lenBuf2 == (SG_uint64)lenBuf1)); VERIFY_COND("create_zero_byte_blob(memcmp)",(memcmp(pbuf1,pbuf2,lenBuf1)==0)); VERIFY_ERR_CHECK_DISCARD( SG_repo__get_hash_method(pCtx, pRepo, &pszHashMethod) ); kLimit = SG_NrElements(az); for (k=0; k<kLimit; k++) { if (strcmp(pszHashMethod,az[k].pszHashMethod) == 0) { // The empty blob should always have this hid VERIFY_COND("zero byte blob hid mismatch", strcmp(pszidHidBlob1, az[k].pszTrivialHash) == 0); } } ////////////////////////////////////////////////////////////////// // cleanup SG_NULLFREE(pCtx, pbuf1); SG_NULLFREE(pCtx, pbuf2); SG_NULLFREE(pCtx, pszidHidBlob1); SG_NULLFREE(pCtx, pszHashMethod); }
int u0001_stdint__test_system(void) { VERIFY_COND( "test_system", (sizeof(size_t) >= 4) ); #if defined(LINUX) || defined(MAC) INFOP("test_system", ("sizeof(off_t) is %d",(SG_uint32)sizeof(off_t))); #endif return 1; }
static int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen) { char *p, *e; if (line==NULL) return 0; p = line; while(p!=NULL && *p!='\n' && *p!='\r' && *p!=0) { INFOP("findArg: %s\n", p); if (os_strncmp(p, arg, os_strlen(arg))==0 && p[os_strlen(arg)]=='=') { p += os_strlen(arg)+1; //move p to start of value e = (char*)os_strstr(p, "&"); if (e==NULL) e = p+os_strlen(p); INFOP("findArg: val %s len %d\n", p, (e-p)); return httpdUrlDecode(p, (e-p), buff, buffLen); } p = (char*)os_strstr(p, "&"); if (p!=NULL) p += 1; } TESTP("Finding %s in %s: Not found\n", arg, line); return -1; //not found }
void ICACHE_FLASH_ATTR switchTimerCb(uint32_t *args) { const swOnMax = 100; const swOffMax = 5; static int switchPulseCount; static enum { IDLE, ON, OFF } switchState = IDLE; if (!easygpio_inputGet(SWITCH)) { // Switch is active LOW switch (switchState) { case IDLE: switchState = ON; switchCount++; switchPulseCount = 1; break; case ON: if (++switchCount > swOnMax) switchCount = swOnMax; break; case OFF: switchState = ON; switchCount = 0; switchPulseCount++; break; default: switchState = IDLE; break; } } else { switch (switchState) { case IDLE: break; case ON: switchCount = 0; switchState = OFF; break; case OFF: if (++switchCount > swOffMax) { switchState = IDLE; switchAction(switchPulseCount); INFOP("SW action %d, light %d\n", switchPulseCount, lightCount); switchPulseCount = 0; } break; default: switchState = IDLE; break; } } if (lightCount >= 1) lightCount--; else lightOff(); }
static uint help_out(struct sk_buff *skb, enum ip_conntrack_info ctinfo, unsigned int matchoff, unsigned int matchlen, struct ip_ct_rtsp_expect* prtspexp, struct nf_conntrack_expect* exp) { char* ptcp; uint tcplen; uint hdrsoff; uint hdrslen; uint lineoff; uint linelen; uint off; //struct iphdr* iph = (struct iphdr*)skb->nh.iph; //struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4); get_skb_tcpdata(skb, &ptcp, &tcplen); hdrsoff = matchoff;//exp->seq - ntohl(tcph->seq); hdrslen = matchlen; off = hdrsoff; pr_debug("NAT rtsp help_out\n"); while (nf_mime_nextline(ptcp, hdrsoff+hdrslen, &off, &lineoff, &linelen)) { if (linelen == 0) { break; } if (off > hdrsoff+hdrslen) { INFOP("!! overrun !!"); break; } pr_debug("hdr: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff); if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) { uint oldtcplen = tcplen; pr_debug("hdr: Transport\n"); if (!rtsp_mangle_tran(ctinfo, exp, prtspexp, skb, lineoff, linelen)) { pr_debug("hdr: Transport mangle failed"); break; } get_skb_tcpdata(skb, &ptcp, &tcplen); hdrslen -= (oldtcplen-tcplen); off -= (oldtcplen-tcplen); lineoff -= (oldtcplen-tcplen); linelen -= (oldtcplen-tcplen); pr_debug("rep: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff); } } return NF_ACCEPT; }
MyMain() { TEMPLATE_MAIN_START; #if defined(HAVE_EXEC_DEBUG_STACKTRACE) BEGIN_TEST( MyFn(test1)(pCtx) ); #else INFOP("u0085_crash", ("Skipping crash stacktrace test....") ); #endif TEMPLATE_MAIN_END; }
static void ICACHE_FLASH_ATTR startUp() { TESTP("\n%s ( %s - %s ) starting ...\n", "MQTT Bridge", wifi_station_get_hostname(), version); INFOP("wifi_get_phy_mode = %d\n", wifi_get_phy_mode()); // os_timer_disarm(&uartTimer); // os_timer_setfn(&uartTimer, (os_timer_func_t *) uartTimerCb, (void *) 0); // os_timer_arm(&uartTimer, 10 * 1000, true); if ( !system_os_task(backgroundTask, USER_TASK_PRIO_1, taskQueue, QUEUE_SIZE)) ERRORP("Can't set up background task\n"); lastAction = INIT_DONE; }
void ICACHE_FLASH_ATTR publishOutput(uint8 idx, uint8 val) { if (mqttIsConnected()) { char *topic = (char*) os_malloc(100), *data = (char*) os_malloc(200); if (topic == NULL || data == NULL) { ERRORP("malloc err %s/%s\n", topic, data); startFlash(-1, 20, 20); // fast return; } os_sprintf(topic, (const char*) "/Raw/%s/%d/info", sysCfg.device_id, idx + OUTPUT_SENSOR_ID_START); os_sprintf(data, (const char*) "{\"Name\":\"OP%d\", \"Type\":\"Output\", \"Value\":\"%d\"}", idx, val); INFOP("%s-->%s", topic, data); if (!MQTT_Publish(mqttClient, topic, data, os_strlen(data), 0, 0)) printMQTTstate(); checkMinHeap(); os_free(topic); os_free(data); } else { INFOP("o/p %d--->%d\n", idx, val); } }
bool ICACHE_FLASH_ATTR passesFilter(char *appTokens[]) { int filterID; bool anyMatched = false; int activeFilters = 0; for (filterID = 0; filterID < FILTER_COUNT; filterID++) { if (strlen(sysCfg.filters[filterID]) > 0) activeFilters++; } if (activeFilters == 0) { INFOP("No filters\n"); return true; } for (filterID = 0; filterID < FILTER_COUNT && !anyMatched; filterID++) { if (strlen(sysCfg.filters[filterID]) > 0) { bool match = true; char *filterTokens[10]; char bfr[100]; // splitString overwrites filter template! strcpy(bfr, sysCfg.filters[filterID]); int tokenCount = splitString((char *) bfr, '/', filterTokens); int tkn; for (tkn = 0; tkn < tokenCount && match; tkn++) { if (strcmp("+", filterTokens[tkn]) == 0) continue; if (strcmp("#", filterTokens[tkn]) == 0) break; if (strcmp(filterTokens[tkn], appTokens[tkn]) != 0) match = false; } if (match) anyMatched = true; } } INFOP("Filter matched %d - (%s)\n", anyMatched, sysCfg.filters[filterID]); return anyMatched; }
void ICACHE_FLASH_ATTR mqttConnectedCb(uint32_t *args) { char topic[100]; MQTT_Client* client = (MQTT_Client*) args; mqttConnected = true; INFOP("MQTT is Connected to %s:%d\n", sysCfg.mqtt_host, sysCfg.mqtt_port); os_sprintf(topic, "/Raw/%s/set/#", sysCfg.device_id); INFOP("Subscribe to: %s\n", topic); MQTT_Subscribe(client, topic, 0); os_sprintf(topic, "/Raw/%s/+/set/filter", sysCfg.device_id); INFOP("Subscribe to: %s\n", topic); MQTT_Subscribe(client, topic, 0); MQTT_Subscribe(client, "/App/#", 0); publishDeviceInfo(client); publishData(client); os_timer_disarm(&switch_timer); os_timer_setfn(&switch_timer, (os_timer_func_t *) switchTimerCb, NULL); os_timer_arm(&switch_timer, 100, true); os_timer_disarm(&display_timer); os_timer_setfn(&display_timer, (os_timer_func_t *) displayCb, NULL); os_timer_arm(&display_timer, 2000, true); os_timer_disarm(&date_timer); os_timer_setfn(&date_timer, (os_timer_func_t *) dateTimerCb, NULL); os_timer_arm(&date_timer, 10 * 60 * 1000, false); //10 minutes os_timer_disarm(&transmit_timer); os_timer_setfn(&transmit_timer, (os_timer_func_t *) transmitCb, (void *) client); os_timer_arm(&transmit_timer, sysCfg.updates * 1000, true); lightOff(); }
int u0020_utf8pathnames__testfilename(SG_string * pStringFilename) { // verify that file name matches what we expect. // // WE RELY ON THE FACT THAT EACH FILENAME IN THE ARRAY STARTS // WITH A DIFFERENT LETTER. const char * szFilename = SG_string__sz(pStringFilename); char c = szFilename[0]; if (c == '.') // "." and ".." return 1; if ((c >= 'A') && (c <= 'Z')) { _tableitem * pti; size_t tableindex = (c - 'A'); SG_bool bTestIsNFC, bTestIsNFD; SG_bool bMatchGiven, bMatchNFC, bMatchNFD; VERIFYP_COND_RETURN("u0020_utf8pathnames",(tableindex < SG_NrElements(table)),("unexpected file [%s]",szFilename)); pti = &table[tableindex ]; // verify that we didn't mess up when creating the test case. bTestIsNFC = (strcmp((char *)pti->pa8,(char *)pti->paNfc) == 0); bTestIsNFD = (strcmp((char *)pti->pa8,(char *)pti->paNfd) == 0); VERIFYP_COND("u0020_utf8pathnames",(bTestIsNFC || bTestIsNFD),("Is tableitem[%c] NFC or NFD?",c)); // see if the filename we got from the system matches what we gave. // if not, see if it matches the NFC() version or the NFD() version. bMatchGiven = (strcmp(szFilename,(char *)pti->pa8) == 0); bMatchNFC = (strcmp(szFilename,(char *)pti->paNfc) == 0); bMatchNFD = (strcmp(szFilename,(char *)pti->paNfd) == 0); INFOP("u0020_utf8pathnames",("tableitem[%c] NFC[%d] [NFC %s NFD] : MatchGiven[%d] MatchNFC[%d] MatchNFD[%d]", c, bTestIsNFC,((bTestIsNFC == bTestIsNFD) ? "==" : "!="), bMatchGiven,bMatchNFC,bMatchNFD)); // // TODO fix this test based upon what we know about the platform. // VERIFYP_COND("u0020_utf8pathnames",(strcmp(szFilename,(char *)pti->pa8)==0),("Received [%s] expected [%s]",szFilename,pti->pa8)); return 1; } VERIFYP_COND_RETURN("u0020_utf8pathnames",(0),("unexpected file [%s]",szFilename)); }
void ICACHE_FLASH_ATTR publishDeviceInfo(char *version, char *mode, uint8 wifiChannel, uint16 wifiConnectTime, char *bestSSID, uint16 vcc) { if (mqttIsConnected()) { char *topic = (char *) os_zalloc(50); char *data = (char *) os_zalloc(500); int idx; struct ip_info ipConfig; if (topic == NULL || data == NULL) { ERRORP("malloc err %s/%s\n", topic, data); startFlash(-1, 50, 50); // fast return; } wifi_get_ip_info(STATION_IF, &ipConfig); os_sprintf(topic, "/Raw/%10s/info", sysCfg.device_id); os_sprintf(data, "{\"Name\":\"%s\", \"Location\":\"%s\", \"Version\":\"%s(%s)\", " "\"Updates\":%d, \"Inputs\":%d, \"Outputs\":%d, " "\"RSSI\":%d, \"Channel\": %d, \"ConnectTime\": %d, \"Vcc\": %d, ", sysCfg.deviceName, sysCfg.deviceLocation, version, mode, sysCfg.updates, #ifdef INPUTS sysCfg.inputs, #else 0, #endif #ifdef OUTPUTS sysCfg.outputs, #else 0, #endif wifi_station_get_rssi(), wifiChannel, wifiConnectTime, vcc); os_sprintf(data + os_strlen(data), "\"IPaddress\":\"%d.%d.%d.%d\"", IP2STR(&ipConfig.ip.addr)); os_sprintf(data + os_strlen(data), ", \"AP\":\"%s\"", bestSSID); os_sprintf(data + os_strlen(data), ", \"Settings\":["); for (idx = 0; idx < SETTINGS_SIZE; idx++) { if (idx != 0) os_sprintf(data + os_strlen(data), ", "); os_sprintf(data + os_strlen(data), "%d", sysCfg.settings[idx]); } os_sprintf(data + os_strlen(data), "]}"); if (!MQTT_Publish(mqttClient, topic, data, os_strlen(data), 0, true)) printMQTTstate(); INFOP("%s=>%s\n", topic, data); checkMinHeap(); os_free(topic); os_free(data); } }
int u0020_utf8pathnames__test(SG_context * pCtx) { SG_pathname * pPathnameTmpDir; int k, kLimit; // create a temporary directory. VERIFY_ERR_CHECK_RETURN( u0020_utf8pathnames__mkdir_tmp_dir(pCtx, &pPathnameTmpDir) ); INFOP("u0020_utf8pathnames",("Creating directory [%s]",SG_pathname__sz(pPathnameTmpDir))); // create a series of files in the temporary directory that have // various unicode characters in their names. kLimit = SG_NrElements(table); for (k=0; k<kLimit; k++) { _tableitem * pti = &table[k]; INFOP("u0020_utf8pathnames",("[%d] starts with [%c]",k,pti->pa8[0])); VERIFY_ERR_CHECK_DISCARD( u0020_utf8pathnames__create_file(pCtx,pPathnameTmpDir,pti) ); } // open the tmp dir for reading and read the filename of each file in it. // compare these with the version of the filename that we used to create // the file. VERIFY_ERR_CHECK_DISCARD( u0020_utf8pathnames__readdir(pCtx, pPathnameTmpDir) ); // clean up our mess VERIFY_ERR_CHECK_DISCARD( SG_fsobj__rmdir_recursive__pathname(pCtx, pPathnameTmpDir) ); SG_PATHNAME_NULLFREE(pCtx, pPathnameTmpDir); return 1; }
/* * Parse an RTSP packet. * * Returns zero if parsing failed. * * Parameters: * IN ptcp tcp data pointer * IN tcplen tcp data len * IN/OUT ptcpoff points to current tcp offset * OUT phdrsoff set to offset of rtsp headers * OUT phdrslen set to length of rtsp headers * OUT pcseqoff set to offset of CSeq header * OUT pcseqlen set to length of CSeq header */ static int rtsp_parse_message(char* ptcp, uint tcplen, uint* ptcpoff, uint* phdrsoff, uint* phdrslen, uint* pcseqoff, uint* pcseqlen) { uint entitylen = 0; uint lineoff; uint linelen; if (!nf_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen)) { return 0; } *phdrsoff = *ptcpoff; while (nf_mime_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen)) { if (linelen == 0) { if (entitylen > 0) { *ptcpoff += min(entitylen, tcplen - *ptcpoff); } break; } if (lineoff+linelen > tcplen) { INFOP("!! overrun !!\n"); break; } if (nf_strncasecmp(ptcp+lineoff, "CSeq:", 5) == 0) { *pcseqoff = lineoff; *pcseqlen = linelen; } if (nf_strncasecmp(ptcp+lineoff, "Content-Length:", 15) == 0) { uint off = lineoff+15; SKIP_WSPACE(ptcp+lineoff, linelen, off); nf_strtou32(ptcp+off, &entitylen); } } *phdrslen = (*ptcpoff) - (*phdrsoff); return 1; }
void MyFn(create_tmp_src_dir)(SG_context * pCtx, SG_pathname ** ppPathnameTempDir) { // create a temp directory in the current directory to be the // home of some userfiles. // caller must free returned value. SG_pathname * pPathnameTempDir = NULL; VERIFY_ERR_CHECK( unittest__alloc_unique_pathname_in_cwd(pCtx,&pPathnameTempDir) ); VERIFY_ERR_CHECK( SG_fsobj__mkdir_recursive__pathname(pCtx, pPathnameTempDir) ); INFOP("mktmpdir",("Temp Src Dir is [%s]",SG_pathname__sz(pPathnameTempDir))); *ppPathnameTempDir = pPathnameTempDir; return; fail: SG_PATHNAME_NULLFREE(pCtx, pPathnameTempDir); }
void ICACHE_FLASH_ATTR publishTemperature(int idx) { struct Temperature *t; if (checkClient("publishTemperature")) { char *topic = (char*) os_malloc(100), *data = (char*) os_malloc(100); if (!checkAlloc(topic, data)) return; if (getUnmappedTemperature(idx, &t)) { os_sprintf(topic, (const char*) "/Raw/%s/%s/info", sysCfg.device_id, t->address); os_sprintf(data, (const char*) "{ \"Type\":\"Temp\", \"Value\":\"%c%d.%02d\"}", t->sign, t->val, t->fract); if (!MQTT_Publish(mqttClient, topic, data, os_strlen(data), 0, 0)) printMQTTstate(); INFOP("%s=>%s\n", topic, data); } checkMinHeap(); os_free(topic); os_free(data); } }
/** * List all of the installed repo implementations. * * NOTE: I don't have a way to verify that the list is complete or verify * NOTE: what it should contain, so I just print the list. */ void MyFn(list_vtables)(SG_context * pCtx) { SG_vhash * pvh_vtables = NULL; SG_uint32 count_vtables; SG_uint32 k; VERIFY_ERR_CHECK( SG_repo__query_implementation(pCtx,NULL, SG_REPO__QUESTION__VHASH__LIST_REPO_IMPLEMENTATIONS, NULL,NULL,NULL,0, &pvh_vtables) ); VERIFY_ERR_CHECK( SG_vhash__count(pCtx,pvh_vtables,&count_vtables) ); for (k=0; k<count_vtables; k++) { const char * pszKey_vtable_k; VERIFY_ERR_CHECK( SG_vhash__get_nth_pair(pCtx,pvh_vtables,k,&pszKey_vtable_k,NULL) ); INFOP("vtable",("Repo Implementation[%d]: [%s]",k,pszKey_vtable_k)); } fail: SG_VHASH_NULLFREE(pCtx, pvh_vtables); }
void MyFn(create_some_blobs_from_bytes)(SG_context * pCtx, SG_repo * pRepo) { SG_uint64 k; char * szRepoId; VERIFY_ERR_CHECK_DISCARD( SG_repo__get_repo_id(pCtx, pRepo, &szRepoId) ); INFOP("create_some_blobs_from_bytes",("RepoID[%s] ", szRepoId )); SG_NULLFREE(pCtx, szRepoId); ////////////////////////////////////////////////////////////////// // create a series of blobs of various known lengths and contents. for (k=1; k <= MyMaxFile; k+= MyStepFile) { SG_ERR_IGNORE( MyFn(create_blob_from_bytes)(pCtx, pRepo,(SG_uint32)k,"Hello World!\nThis is line 2.\n") ); SG_ERR_IGNORE( MyFn(create_blob_from_bytes)(pCtx, pRepo,(SG_uint32)k,"Welcome to the middle of the film!\n") ); } }
static void ICACHE_FLASH_ATTR backgroundTask(os_event_t *e) { static RcvMsgBuff *tempRcv = NULL; INFOP("Background task %d\n", e->sig); switch (e->sig) { case EVENT_RX: processRxFunc(tempRcv = (RcvMsgBuff *)e->par); break; case EVENT_RX_OVERFLOW: ERRORP("Rx overflow\n"); processRxFunc((RcvMsgBuff *)e->par); break; // case EVENT_UART_TIMER: // if (tempRcv) // TESTP("UART c %d, r %d, w %d, s %x\n", tempRcv->count, tempRcv->pReadPos, // tempRcv->pWritePos, READ_PERI_REG(UART_INT_CLR(0))); // break; default: ERRORP("Bad background task event %d\n", e->sig); break; } }
void ICACHE_FLASH_ATTR publishDeviceReset(char *version, int lastAction) { if (mqttIsConnected()) { char *topic = (char *) os_zalloc(50); char *data = (char *) os_zalloc(200); int idx; if (topic == NULL || data == NULL) { ERRORP("malloc err %s/%s\n", topic, data); startFlash(-1, 50, 50); // fast return; } os_sprintf(topic, "/Raw/%10s/reset", sysCfg.device_id); os_sprintf(data, "{\"Name\":\"%s\", \"Location\":\"%s\", \"Version\":\"%s\", \"Reason\":%d, \"LastAction\":%d}", sysCfg.deviceName, sysCfg.deviceLocation, version, system_get_rst_info()->reason, lastAction); if (!MQTT_Publish(mqttClient, topic, data, os_strlen(data), 0, false)) printMQTTstate(); INFOP("%s=>%s\n", topic, data); checkMinHeap(); os_free(topic); os_free(data); } }
/* * Mangle the "Transport:" header: * - Replace all occurences of "client_port=<spec>" * - Handle destination parameter * * In: * ct, ctinfo = conntrack context * skb = packet * tranoff = Transport header offset from TCP data * tranlen = Transport header length (incl. CRLF) * rport_lo = replacement low port (host endian) * rport_hi = replacement high port (host endian) * * Returns packet size difference. * * Assumes that a complete transport header is present, ending with CR or LF */ static int rtsp_mangle_tran(enum ip_conntrack_info ctinfo, struct nf_conntrack_expect *exp, struct ip_ct_rtsp_expect *prtspexp, struct sk_buff *skb, uint tranoff, uint tranlen) { char* ptcp; uint tcplen; char* ptran; char rbuf1[16]; /* Replacement buffer (one port) */ uint rbuf1len; /* Replacement len (one port) */ char rbufa[16]; /* Replacement buffer (all ports) */ uint rbufalen; /* Replacement len (all ports) */ u_int32_t newip; u_int16_t loport, hiport; uint off = 0; uint diff; /* Number of bytes we removed */ struct nf_conn *ct = exp->master; struct nf_conntrack_tuple *t; char szextaddr[15+1]; uint extaddrlen; int is_stun; get_skb_tcpdata(skb, &ptcp, &tcplen); ptran = ptcp+tranoff; if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen || tranlen < 10 || !iseol(ptran[tranlen-1]) || nf_strncasecmp(ptran, "Transport:", 10) != 0) { INFOP("sanity check failed\n"); return 0; } off += 10; SKIP_WSPACE(ptcp+tranoff, tranlen, off); newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip; t = &exp->tuple; t->dst.u3.ip = newip; extaddrlen = extip ? sprintf(szextaddr, "%pI4", &extip) : sprintf(szextaddr, "%pI4", &newip); pr_debug("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto")); rbuf1len = rbufalen = 0; switch (prtspexp->pbtype) { case pb_single: for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ { t->dst.u.udp.port = htons(loport); if (nf_conntrack_expect_related(exp) == 0) { pr_debug("using port %hu\n", loport); break; } } if (loport != 0) { rbuf1len = sprintf(rbuf1, "%hu", loport); rbufalen = sprintf(rbufa, "%hu", loport); } break; case pb_range: for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */ { t->dst.u.udp.port = htons(loport); if (nf_conntrack_expect_related(exp) == 0) { hiport = loport + 1; //~exp->mask.dst.u.udp.port; pr_debug("using ports %hu-%hu\n", loport, hiport); break; } } if (loport != 0) { rbuf1len = sprintf(rbuf1, "%hu", loport); rbufalen = sprintf(rbufa, "%hu-%hu", loport, loport+1); } break; case pb_discon: for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ { t->dst.u.udp.port = htons(loport); if (nf_conntrack_expect_related(exp) == 0) { pr_debug("using port %hu (1 of 2)\n", loport); break; } } for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */ { t->dst.u.udp.port = htons(hiport); if (nf_conntrack_expect_related(exp) == 0) { pr_debug("using port %hu (2 of 2)\n", hiport); break; } } if (loport != 0 && hiport != 0) { rbuf1len = sprintf(rbuf1, "%hu", loport); if (hiport == loport+1) { rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport); } else { rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport); } } break; } if (rbuf1len == 0) { return 0; /* cannot get replacement port(s) */ } /* Transport: tran;field;field=val,tran;field;field=val,... */ while (off < tranlen) { uint saveoff; const char* pparamend; uint nextparamoff; pparamend = memchr(ptran+off, ',', tranlen-off); pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1; nextparamoff = pparamend-ptcp; /* * We pass over each param twice. On the first pass, we look for a * destination= field. It is handled by the security policy. If it * is present, allowed, and equal to our external address, we assume * that STUN is being used and we leave the client_port= field alone. */ is_stun = 0; saveoff = off; while (off < nextparamoff) { const char* pfieldend; uint nextfieldoff; pfieldend = memchr(ptran+off, ';', nextparamoff-off); nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0) { if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0) { is_stun = 1; } if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun)) { diff = nextfieldoff-off; if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, off, diff, NULL, 0)) { /* mangle failed, all we can do is bail */ nf_conntrack_unexpect_related(exp); return 0; } get_skb_tcpdata(skb, &ptcp, &tcplen); ptran = ptcp+tranoff; tranlen -= diff; nextparamoff -= diff; nextfieldoff -= diff; } } off = nextfieldoff; } if (is_stun) { continue; } off = saveoff; while (off < nextparamoff) { const char* pfieldend; uint nextfieldoff; pfieldend = memchr(ptran+off, ';', nextparamoff-off); nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; if (strncmp(ptran+off, "client_port=", 12) == 0) { u_int16_t port; uint numlen; uint origoff; uint origlen; char* rbuf = rbuf1; uint rbuflen = rbuf1len; off += 12; origoff = (ptran-ptcp)+off; origlen = 0; numlen = nf_strtou16(ptran+off, &port); off += numlen; origlen += numlen; if (port != prtspexp->loport) { pr_debug("multiple ports found, port %hu ignored\n", port); } else { if (ptran[off] == '-' || ptran[off] == '/') { off++; origlen++; numlen = nf_strtou16(ptran+off, &port); off += numlen; origlen += numlen; rbuf = rbufa; rbuflen = rbufalen; } /* * note we cannot just memcpy() if the sizes are the same. * the mangle function does skb resizing, checks for a * cloned skb, and updates the checksums. * * parameter 4 below is offset from start of tcp data. */ diff = origlen-rbuflen; if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, origoff, origlen, rbuf, rbuflen)) { /* mangle failed, all we can do is bail */ nf_conntrack_unexpect_related(exp); return 0; } get_skb_tcpdata(skb, &ptcp, &tcplen); ptran = ptcp+tranoff; tranlen -= diff; nextparamoff -= diff; nextfieldoff -= diff; } } off = nextfieldoff; } off = nextparamoff; } return 1; }
/* outbound packet: client->server */ static inline int help_out(struct sk_buff **pskb, unsigned char *rb_ptr, unsigned int datalen, struct ip_conntrack* ct, enum ip_conntrack_info ctinfo) { struct ip_ct_rtsp_expect expinfo; int dir = CTINFO2DIR(ctinfo); /* = IP_CT_DIR_ORIGINAL */ //struct tcphdr* tcph = (void*)iph + iph->ihl * 4; //uint tcplen = pktlen - iph->ihl * 4; char* pdata = rb_ptr; //uint datalen = tcplen - tcph->doff * 4; uint dataoff = 0; int ret = NF_ACCEPT; struct ip_conntrack_expect *exp; memset(&expinfo, 0, sizeof(expinfo)); while (dataoff < datalen) { uint cmdoff = dataoff; uint hdrsoff = 0; uint hdrslen = 0; uint cseqoff = 0; uint cseqlen = 0; uint lineoff = 0; uint linelen = 0; uint off; if (!rtsp_parse_message(pdata, datalen, &dataoff, &hdrsoff, &hdrslen, &cseqoff, &cseqlen)) { break; /* not a valid message */ } if (strncmp(pdata+cmdoff, "SETUP ", 6) != 0) { continue; /* not a SETUP message */ } DEBUGP("found a setup message\n"); off = 0; while (nf_mime_nextline(pdata+hdrsoff, hdrslen, &off, &lineoff, &linelen)) { if (linelen == 0) { break; } if (off > hdrsoff+hdrslen) { INFOP("!! overrun !!"); break; } if (nf_strncasecmp(pdata+hdrsoff+lineoff, "Transport:", 10) == 0) { rtsp_parse_transport(pdata+hdrsoff+lineoff, linelen, &expinfo); } } if (expinfo.loport == 0) { DEBUGP("no udp transports found\n"); continue; /* no udp transports found */ } DEBUGP("udp transport found, ports=(%d,%hu,%hu)\n", (int)expinfo.pbtype, expinfo.loport, expinfo.hiport); exp = ip_conntrack_expect_alloc(ct); if (!exp) { ret = NF_DROP; goto out; } //exp->seq = ntohl(tcph->seq) + hdrsoff; /* mark all the headers */ exp->master = ct; //exp.help.exp_rtsp_info.len = hdrslen; exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip; exp->mask.src.ip = 0xffffffff; exp->tuple.dst.ip = ct->tuplehash[dir].tuple.src.ip; exp->mask.dst.ip = 0xffffffff; exp->tuple.dst.u.udp.port = expinfo.loport; exp->mask.dst.u.udp.port = (expinfo.pbtype == pb_range) ? 0xfffe : 0xffff; exp->tuple.dst.protonum = IPPROTO_UDP; exp->mask.dst.protonum = 0xff; DEBUGP("expect_related %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n", NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port), NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port)); if (ip_nat_rtsp_hook) /* pass the request off to the nat helper */ ret = ip_nat_rtsp_hook(pskb, ctinfo, &expinfo, exp); else if (ip_conntrack_expect_related(exp) != 0) { INFOP("ip_conntrack_expect_related failed\n"); ip_conntrack_expect_put(exp); ret = NF_DROP; } goto out; } out: return ret; }
/* * Find lo/hi client ports (if any) in transport header * In: * ptcp, tcplen = packet * tranoff, tranlen = buffer to search * * Out: * pport_lo, pport_hi = lo/hi ports (host endian) * * Returns nonzero if any client ports found * * Note: it is valid (and expected) for the client to request multiple * transports, so we need to parse the entire line. */ static int rtsp_parse_transport(char* ptran, uint tranlen, struct ip_ct_rtsp_expect* prtspexp) { int rc = 0; uint off = 0; if (tranlen < 10 || !iseol(ptran[tranlen-1]) || nf_strncasecmp(ptran, "Transport:", 10) != 0) { INFOP("sanity check failed\n"); return 0; } DEBUGP("tran='%.*s'\n", (int)tranlen, ptran); off += 10; SKIP_WSPACE(ptran, tranlen, off); /* Transport: tran;field;field=val,tran;field;field=val,... */ while (off < tranlen) { const char* pparamend; uint nextparamoff; pparamend = memchr(ptran+off, ',', tranlen-off); pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1; nextparamoff = pparamend-ptran; while (off < nextparamoff) { const char* pfieldend; uint nextfieldoff; pfieldend = memchr(ptran+off, ';', nextparamoff-off); nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; if (strncmp(ptran+off, "client_port=", 12) == 0) { u_int16_t port; uint numlen; off += 12; numlen = nf_strtou16(ptran+off, &port); off += numlen; if (prtspexp->loport != 0 && prtspexp->loport != port) { DEBUGP("multiple ports found, port %hu ignored\n", port); } else { prtspexp->loport = prtspexp->hiport = port; if (ptran[off] == '-') { off++; numlen = nf_strtou16(ptran+off, &port); off += numlen; prtspexp->pbtype = pb_range; prtspexp->hiport = port; // If we have a range, assume rtp: // loport must be even, hiport must be loport+1 if ((prtspexp->loport & 0x0001) != 0 || prtspexp->hiport != prtspexp->loport+1) { DEBUGP("incorrect range: %hu-%hu, correcting\n", prtspexp->loport, prtspexp->hiport); prtspexp->loport &= 0xfffe; prtspexp->hiport = prtspexp->loport+1; } } else if (ptran[off] == '/') { off++; numlen = nf_strtou16(ptran+off, &port); off += numlen; prtspexp->pbtype = pb_discon; prtspexp->hiport = port; } rc = 1; } } /* * Note we don't look for the destination parameter here. * If we are using NAT, the NAT module will handle it. If not, * and the client is sending packets elsewhere, the expectation * will quietly time out. */ off = nextfieldoff; } off = nextparamoff; } return rc; }
void MyFn(create_blob_from_file)(SG_context * pCtx, SG_repo * pRepo, const SG_pathname * pPathnameTempDir, SG_uint64 lenFile, const char * szSrc) { // create a file of length "lenFile" in the temp directory. // use it to create a blob. // try to create it a second time and verify that we get an duplicate-hid error. char* pszidGidRandom1 = NULL; char* pszidGidRandom2 = NULL; SG_pathname * pPathnameTempFile1 = NULL; SG_pathname * pPathnameTempFile2 = NULL; SG_file * pFileTempFile1 = NULL; SG_file * pFileTempFile2 = NULL; SG_uint32 lenSrc; SG_uint64 lenWritten; char* pszidHidBlob1 = NULL; char* pszidHidBlob1Dup = NULL; char* pszidHidBlob2 = NULL; char* pszidHidVerify1 = NULL; char* pszidHidVerify2 = NULL; SG_bool bEqual; SG_repo_tx_handle* pTx = NULL; SG_uint64 iBlobFullLength = 0; ////////////////////////////////////////////////////////////////// // create temp-file-1 of length "lenFile" in the temp directory. VERIFY_ERR_CHECK_DISCARD( SG_gid__alloc(pCtx, &pszidGidRandom1) ); VERIFY_ERR_CHECK_DISCARD( SG_gid__alloc(pCtx, &pszidGidRandom2) ); VERIFY_ERR_CHECK_DISCARD( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathnameTempFile1,pPathnameTempDir,(pszidGidRandom1)) ); VERIFY_ERR_CHECK_DISCARD( SG_file__open__pathname(pCtx, pPathnameTempFile1,SG_FILE_RDWR|SG_FILE_CREATE_NEW,0644,&pFileTempFile1) ); // write random gid at the beginning of the file // so that we won't get collisions if we are called // multiple times. VERIFY_ERR_CHECK_DISCARD( SG_file__write(pCtx, pFileTempFile1,(SG_uint32)strlen(pszidGidRandom1),(SG_byte *)pszidGidRandom1,NULL) ); VERIFY_ERR_CHECK_DISCARD( SG_file__write(pCtx, pFileTempFile1,1,(SG_byte *)"\n",NULL) ); // generate lots of data in the file so that we'll cause the // blob routines to exercise the chunking stuff. lenSrc = (SG_uint32)strlen(szSrc); lenWritten = 0; while (lenWritten < lenFile) { VERIFY_ERR_CHECK_DISCARD( SG_file__write(pCtx, pFileTempFile1,lenSrc,(SG_byte *)szSrc,NULL) ); lenWritten += lenSrc; } // the test file does NOT have a final LF. i'm not sure it matters one way or the // other, but i'm just saying that we're not putting on a final LF. SG_ERR_IGNORE( SG_file__seek(pCtx, pFileTempFile1,0) ); ////////////////////////////////////////////////////////////////// // use currently open temp file to create a blob. // we get the HID back. (we need to free it later.) VERIFY_ERR_CHECK_DISCARD( SG_repo__begin_tx(pCtx, pRepo, &pTx) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__store_blob_from_file(pCtx, pRepo,pTx,NULL,SG_FALSE,pFileTempFile1,&pszidHidBlob1,&iBlobFullLength) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__commit_tx(pCtx, pRepo, &pTx) ); INFOP("create_blob_from_file",("Created blob [%s]",(pszidHidBlob1))); ////////////////////////////////////////////////////////////////// // try to create blob again and verify we get an duplicate-hid error. // Ian TODO: Put this back when SG_ERR_BLOBFILEALREADYEXISTS has been replaced. // VERIFY_ERR_CHECK_DISCARD( SG_repo__begin_tx(pCtx, pRepo, &pTx) ); // err = SG_repo__store_blob_from_file(pRepo,pTx,SG_FALSE,pFileTempFile1,&pszidHidBlob1Dup); // VERIFYP_CTX_ERR_IS("create_blob_from_file(duplicate)", pCtx, SG_ERR_BLOBFILEALREADYEXISTS, ("Duplicate create failed [%s][%s]",pszidHidBlob1,pszidHidBlob1Dup)); // VERIFY_ERR_CHECK_DISCARD( SG_repo__commit_tx(pCtx, pRepo, SG_DAGNUM__NONE, NULL, &pTx) ); ////////////////////////////////////////////////////////////////// // create empty temp-file-2 and try to read the blob from the repo. VERIFY_ERR_CHECK_DISCARD( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathnameTempFile2,pPathnameTempDir,(pszidGidRandom2)) ); VERIFY_ERR_CHECK_DISCARD( SG_file__open__pathname(pCtx, pPathnameTempFile2,SG_FILE_RDWR|SG_FILE_CREATE_NEW,0644,&pFileTempFile2) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__fetch_blob_into_file(pCtx, pRepo,pszidHidBlob1,pFileTempFile2,NULL) ); ////////////////////////////////////////////////////////////////// // verify that the contents of temp-file-2 is identical to the // contents of temp-file-1. (we already know that the HIDs match // and was verified during the fetch, but there are times when the // HID is just being used as a key -- it doesn't mean that what we // actually restored is correct. VERIFY_ERR_CHECK_DISCARD( SG_repo__alloc_compute_hash__from_file(pCtx, pRepo, pFileTempFile1, &pszidHidVerify1) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__alloc_compute_hash__from_file(pCtx, pRepo, pFileTempFile2, &pszidHidVerify2) ); bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidVerify2))); VERIFY_COND("create_blob_from_file(verify v1==v2)",bEqual); bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidBlob1))); VERIFY_COND("create_blob_from_file(verify v1==id)",bEqual); ////////////////////////////////////////////////////////////////// // TODO delete temp source file SG_ERR_IGNORE( SG_file__close(pCtx, &pFileTempFile1) ); SG_ERR_IGNORE( SG_file__close(pCtx, &pFileTempFile2) ); ////////////////////////////////////////////////////////////////// // cleanup SG_NULLFREE(pCtx, pszidGidRandom1); SG_NULLFREE(pCtx, pszidGidRandom2); SG_NULLFREE(pCtx, pszidHidBlob1); SG_NULLFREE(pCtx, pszidHidBlob1Dup); SG_NULLFREE(pCtx, pszidHidBlob2); SG_NULLFREE(pCtx, pszidHidVerify1); SG_NULLFREE(pCtx, pszidHidVerify2); SG_PATHNAME_NULLFREE(pCtx, pPathnameTempFile1); SG_PATHNAME_NULLFREE(pCtx, pPathnameTempFile2); }
void MyFn(create_blob_from_bytes)(SG_context * pCtx, SG_repo * pRepo, SG_uint32 lenBuf1, const char * szSrc) { // create a large buffer containing some known data. // use it to create a blob directly from the buffer. // read it back from the repo and verify it. char* pszidTidRandom1 = NULL; char* pszidTidRandom2 = NULL; SG_uint32 lenSrc; char* pszidHidBlob1 = NULL; char* pszidHidBlob1Dup = NULL; char* pszidHidBlob2 = NULL; char* pszidHidVerify1 = NULL; char* pszidHidVerify2 = NULL; SG_bool bEqual; char * pbuf1 = NULL; char * pbuf2 = NULL; char * pbuf1End; char * p1; SG_uint64 lenBuf2; SG_repo_tx_handle* pTx = NULL; SG_repo_fetch_blob_handle* pFetchHandle = NULL; SG_uint64 lenAbortedBlob; SG_uint32 lenGotAbortedBlob; SG_bool b_done = SG_FALSE; ////////////////////////////////////////////////////////////////// SG_ERR_IGNORE( SG_tid__alloc2(pCtx, &pszidTidRandom1, 32) ); SG_ERR_IGNORE( SG_tid__alloc2(pCtx, &pszidTidRandom2, 32) ); if (lenBuf1 < 100) lenBuf1 += 100; pbuf1 = (char *)SG_calloc(1,lenBuf1+1); pbuf1End = pbuf1+lenBuf1; p1 = pbuf1; // write random gid at the beginning of the buffer // so that we won't get collisions if we are called // multiple times. memcpy(p1,pszidTidRandom1,strlen(pszidTidRandom1)); p1 += strlen(pszidTidRandom1); *p1++ = '\n'; // generate lots of data in the file so that we'll cause the // blob routines to exercise the chunking stuff. lenSrc = (SG_uint32)strlen(szSrc); while (p1+lenSrc < pbuf1End) { memcpy(p1,szSrc,lenSrc); p1 += lenSrc; } // use the buffer to create a blob in the repo. we use lenBuf1 as the // length rather than (p1-pbuf1) so we may have some nulls at the end. // hope this is ok??? i guess we'll find out... VERIFY_ERR_CHECK_DISCARD( SG_repo__begin_tx(pCtx, pRepo, &pTx) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__store_blob_from_memory(pCtx, pRepo,pTx,NULL,SG_FALSE,(SG_byte *)pbuf1,lenBuf1,&pszidHidBlob1) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__commit_tx(pCtx, pRepo, &pTx) ); INFOP("create_blob_from_bytes",("Created blob [%s]",(pszidHidBlob1))); ////////////////////////////////////////////////////////////////// // try to create blob again and verify we get an duplicate-hid error. // Ian TODO: Put this back when SG_ERR_BLOBFILEALREADYEXISTS is replaced. // VERIFY_ERR_CHECK_DISCARD( SG_repo__begin_tx(pCtx, pRepo, &pTx) ); // err = SG_repo__store_blob_from_memory(pRepo,pTx,SG_FALSE,(SG_byte *)pbuf1,lenBuf1,&pszidHidBlob1Dup); // VERIFYP_CTX_ERR_IS("create_blob_from_bytes(duplicate)", pCtx, SG_ERR_BLOBFILEALREADYEXISTS, ("Duplicate create failed [%s][%s]",pszidHidBlob1,pszidHidBlob1Dup)); // VERIFY_ERR_CHECK_DISCARD( SG_repo__commit_tx(pCtx, pRepo, SG_DAGNUM__NONE, NULL, &pTx) ); ////////////////////////////////////////////////////////////////// // abort a fetch, ensure it doesn't interfere with subsequent complete fetch VERIFY_ERR_CHECK_DISCARD( SG_repo__fetch_blob__begin(pCtx, pRepo, pszidHidBlob1, SG_TRUE, NULL, NULL, NULL, NULL, &lenAbortedBlob, &pFetchHandle) ); // We want to abort mid-blob, so we set an arbitrary (but small) chunk size, and verify that the blob is // bigger than it. VERIFY_ERR_CHECK_DISCARD( SG_repo__fetch_blob__chunk(pCtx, pRepo, pFetchHandle, 64, (SG_byte*)pbuf1, &lenGotAbortedBlob, &b_done) ); VERIFY_COND("create_blob_from_bytes(fetch abort sufficient length)", lenAbortedBlob > lenGotAbortedBlob); VERIFY_ERR_CHECK_DISCARD( SG_repo__fetch_blob__abort(pCtx, pRepo, &pFetchHandle) ); VERIFY_COND("create_blob_from_bytes(fetch abort freed handle)", !pFetchHandle); ////////////////////////////////////////////////////////////////// // fetch blob into a new buffer and verify that it matches. VERIFY_ERR_CHECK_DISCARD( SG_repo__fetch_blob_into_memory(pCtx, pRepo,pszidHidBlob1,(SG_byte **)&pbuf2,&lenBuf2) ); VERIFY_COND("create_blob_from_bytes(fetch blob)",(lenBuf2 == (SG_uint64)lenBuf1)); ////////////////////////////////////////////////////////////////// // verify that the contents of buf-2 is identical to the contents of buf-1. // (we already know that the HIDs match and was verified during the fetch, // but there are times when the HID is just being used as a key -- it // doesn't mean that what we actually restored is correct. VERIFY_ERR_CHECK_DISCARD( SG_repo__alloc_compute_hash__from_bytes(pCtx, pRepo, lenBuf1, (SG_byte *)pbuf1, &pszidHidVerify1) ); VERIFY_ERR_CHECK_DISCARD( SG_repo__alloc_compute_hash__from_bytes(pCtx, pRepo, (SG_uint32)lenBuf2, (SG_byte *)pbuf2, &pszidHidVerify2) ); bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidVerify2))); VERIFY_COND("create_blob_from_bytes(verify v1==v2)",bEqual); bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidBlob1))); VERIFY_COND("create_blob_from_bytes(verify v1==id)",bEqual); VERIFY_COND("creata_blob_from_bytes(memcmp)",(memcmp(pbuf1,pbuf2,lenBuf1)==0)); ////////////////////////////////////////////////////////////////// // cleanup SG_NULLFREE(pCtx, pbuf1); SG_NULLFREE(pCtx, pbuf2); SG_NULLFREE(pCtx, pszidTidRandom1); SG_NULLFREE(pCtx, pszidTidRandom2); SG_NULLFREE(pCtx, pszidHidBlob1); SG_NULLFREE(pCtx, pszidHidBlob1Dup); SG_NULLFREE(pCtx, pszidHidBlob2); SG_NULLFREE(pCtx, pszidHidVerify1); SG_NULLFREE(pCtx, pszidHidVerify2); }