Can't get file using "GetSectionFromAnyFv" or going over all files using firmware volume protocol->GetNextFile - uefi

I donwloaded BIOS rom and get list of files using UEFITool:
ROM Structure
So i know "names" of all files that exist. Then i tried to get file using "GetSectionFromAnyFv" but can't get all files, just files in volume under red arrow. For example volume under violet arrow also have files, but i can't get it.
LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NumberOfHandles, &HandleBuffer) return only 1 handle [NumberOfHandles = 1], but as i can see there are more than 1 volume.
Same if i try get file using for(for NumberOfHandles) and iterate over all files getting guids. Just can't get all files.
What could be the problem?
P.S.: ProcessFirmwareVolume for every FV2 HOBs return 20 so that means that "firmware volume block protocol" is alredy processed.
#include "FileByGuid.h"
EFI_GUID TextToGuid(CHAR16* stGUID)
{
EFI_GUID NameGuid;
stGUID[8] = '\0';
stGUID[13] = '\0';
stGUID[18] = '\0';
NameGuid.Data1 = (UINT32)StrHexToUintn(&stGUID[0]);
NameGuid.Data2 = (UINT16)StrHexToUintn(&stGUID[9]);
NameGuid.Data3 = (UINT16)StrHexToUintn(&stGUID[14]);
for (int i = 23; i < 37; i++)
{
Print(L"");
stGUID[i] = stGUID[i + 1];
}
UINTN D4 = StrHexToUintn(&stGUID[19]);
for (int i = 7; i >= 0; i--)
{
NameGuid.Data4[i] = (UINT8)(D4 & 0xFF);
D4 = D4 >> 8;
}
return NameGuid;
}
EFI_STATUS
EFIAPI
FileByGuidDriverEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE* SystemTable
)
{
EFI_FIRMWARE_VOLUME2_PROTOCOL* fv;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL* fvb;
EFI_DEVICE_PATH_PROTOCOL* dp;
EFI_BLOCK_IO2_PROTOCOL* bio;
EFI_BLOCK_IO_PROTOCOL* bio2;
EFI_FILE_PROTOCOL *OpenedFileHandle;
EFI_FILE_HANDLE Root;
EFI_STATUS Status, GetSectionStatus;
UINTN index;
EFI_HANDLE *sfsHandleBuffer = NULL;
EFI_HANDLE *fvHandleBuffer = NULL;
EFI_HANDLE *fvbHandleBuffer = NULL;
EFI_HANDLE* bioHandleBuffer = NULL;
EFI_HANDLE* bio2HandleBuffer = NULL;
EFI_HANDLE FvProtocolHandle;
UINTN sfsHandleCount = 0;
UINTN fvHandleCount = 0;
UINTN fvbHandleCount = 0;
UINTN bioHandleCount = 0;
UINTN bio2HandleCount = 0;
UINTN Size;
EFI_FV_FILETYPE FileType;
UINTN counter = 0;
VOID *Buffer;
VOID *Key;
EFI_GUID fvNameGuid;
EFI_GUID NameGuid;
CHAR16* stGUID = L"114CA60C-D965-4C13-BEF7-C4062248E1FA";
// UINTN EventIndex;
// EFI_INPUT_KEY Keys;
EFI_FV_FILE_ATTRIBUTES Attributes;
EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader;
EFI_PEI_HOB_POINTERS Hob;
// BOOLEAN MediaPresent;
// PARTITION_DETECT_ROUTINE* Routine;
// BOOLEAN MediaPresent;
// EFI_DISK_IO_PROTOCOL* DiskIo;
// EFI_DISK_IO2_PROTOCOL* DiskIo2;
gBS->SetWatchdogTimer(0, 0, 0, NULL);
gST = SystemTable;
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolumeBlock2ProtocolGuid, NULL, &fvbHandleCount, &fvbHandleBuffer);
AsciiPrint("\r\nfv2_block_HandleCount: %d\r\n", fvbHandleCount);
for (index = 0; index < (int)fvbHandleCount; index++)
{
//Status = gBS->OpenProtocol(fvbHandleBuffer[index], &gEfiFirmwareVolumeBlock2ProtocolGuid, (VOID**)&fvb, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
Status = gBS->HandleProtocol(fvbHandleBuffer[index], &gEfiFirmwareVolume2ProtocolGuid, &fvb);
AsciiPrint("-HP fv_block fv2 Status: %d; DevicePath: %s\r\n", Status, ConvertDevicePathToText(DevicePathFromHandle(fvbHandleBuffer[index]), TRUE, TRUE));
}
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &sfsHandleCount, &sfsHandleBuffer);
AsciiPrint("\r\nsfsHandleCount: %d\r\n", sfsHandleCount);
for (index = 0; index < (int)sfsHandleCount; index++)
AsciiPrint("-sfs[%d] handle: %d; device path: %s\r\n", index, sfsHandleBuffer[index], ConvertDevicePathToText(DevicePathFromHandle(sfsHandleBuffer[index]), TRUE, TRUE));
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &sfsHandleCount, &sfsHandleBuffer);
AsciiPrint("\r\nDevicePathHandleCount: %d\r\n", sfsHandleCount);
//for (index = 0; index < (int)sfsHandleCount; index++)
// AsciiPrint("dp[%d] device path: %s\r\n", index, ConvertDevicePathToText(DevicePathFromHandle(sfsHandleBuffer[index]), TRUE, TRUE));
AsciiPrint("\r\nHOB:\r\n");
for (Hob.Raw = GetHobList(); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob))
{
if (GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV2 || GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV || GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV3)
{
FvProtocolHandle = NULL;
FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)(Hob.FirmwareVolume->BaseAddress);
Status = gDS->ProcessFirmwareVolume(FirmwareVolumeHeader, Hob.FirmwareVolume2->Length, &FvProtocolHandle);
if (GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV3)
AsciiPrint("-FV3: Status: %d; FvProtocolHandle: %d; Extracted?:%d; AuthenStatus:%d;\r\n GUID:%g\r\n", Status, FvProtocolHandle, Hob.FirmwareVolume3->ExtractedFv, Hob.FirmwareVolume3->AuthenticationStatus, Hob.FirmwareVolume3->FvName);
else if (GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV2)
AsciiPrint("-FV2: Status: %d; FvProtocolHandle: %d; FileName: %g; \r\n GUID:%g\r\n", Status, FvProtocolHandle, Hob.FirmwareVolume2->FileName, Hob.FirmwareVolume2->FvName);
else
AsciiPrint("-FV: Status: %d; FvProtocolHandle: %d\r\n", Status, FvProtocolHandle);
}
}
AsciiPrint("End HOB\r\n");
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &fvHandleCount, &fvHandleBuffer);
AsciiPrint("\r\nfv2HandleCount: %d\r\n", fvHandleCount);
for (index = 0; index < (int) fvHandleCount; index++)
{
Status = gBS->HandleProtocol(fvHandleBuffer[index], &gEfiFirmwareVolume2ProtocolGuid, (VOID**) &fv);
AsciiPrint("-index: %d; HPfvStatus: %d; DevicePath: %s\r\n", index, Status, ConvertDevicePathToText(DevicePathFromHandle(fvbHandleBuffer[index]), TRUE, TRUE));
if (EFI_ERROR(Status))
continue;
FileType = EFI_FV_FILETYPE_ALL;
Key = AllocatePool(fv->KeySize);
ZeroMem(Key, fv->KeySize);
Status = fv->GetNextFile(fv, Key, &FileType, &fvNameGuid, &Attributes, &Size);
while (Status!= EFI_NOT_FOUND)
{
FileType = EFI_FV_FILETYPE_ALL;
counter++;
//if (counter % 15 == 0)
// AsciiPrint("Status: %d; __file_GUID:%g\r\n", Status, fvNameGuid);
Status = fv->GetNextFile(fv, Key, &FileType, &fvNameGuid, &Attributes, &Size);
}
AsciiPrint("sectionFilesCount: %d\r\n", counter);
counter = 0;
FreePool(Key);
}
NameGuid = TextToGuid(stGUID);
//AsciiPrint("\r\n%g\r\n", NameGuid);
GetSectionStatus = GetSectionFromAnyFv(&NameGuid, EFI_SECTION_ALL, 0, (VOID**)&Buffer, &Size);
AsciiPrint("GetSectionFromAnyFvStatus = %d\r\n", Status);
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &bioHandleCount, &bioHandleBuffer);
AsciiPrint("\r\nbioHandleCount: %d\r\n", bioHandleCount);
for (index = 0; index < (int)bioHandleCount; index++)
{
Status = gBS->HandleProtocol(bioHandleBuffer[index], &gEfiBlockIoProtocolGuid, &bio);
dp = DevicePathFromHandle(bioHandleBuffer[index]);
while (!IsDevicePathEnd(NextDevicePathNode(dp)))
dp = NextDevicePathNode(dp);
AsciiPrint("-HP BlockIO Status: %d; handle: %d; DevicePath: %s\r\n", Status, bioHandleBuffer[index], ConvertDevicePathToText(dp, TRUE, TRUE));
AsciiPrint("--MediaPresent: %d; RemovableMedia: %d; LogicalPartition: %d\r\n", bio->Media->MediaPresent, bio->Media->RemovableMedia, bio->Media->LogicalPartition);
}
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIo2ProtocolGuid, NULL, &bio2HandleCount, &bio2HandleBuffer);
AsciiPrint("\r\nbio2HandleCount: %d\r\n", bio2HandleCount);
for (index = 0; index < (int)bio2HandleCount; index++)
{
Status = gBS->HandleProtocol(bio2HandleBuffer[index], &gEfiBlockIo2ProtocolGuid, &bio2);
dp = DevicePathFromHandle(bio2HandleBuffer[index]);
while (!IsDevicePathEnd(NextDevicePathNode(dp)))
dp = NextDevicePathNode(dp);
AsciiPrint("-HP BlockIO2 Status: %d; handle: %d; DevicePath: %s\r\n", Status, bio2HandleBuffer[index], ConvertDevicePathToText(dp, TRUE, TRUE));
AsciiPrint("--MediaPresent: %d; RemovableMedia: %d; LogicalPartition: %d\r\n", bio2->Media->MediaPresent, bio2->Media->RemovableMedia, bio2->Media->LogicalPartition);
}
AsciiPrint("\r\n");
//save
if (!EFI_ERROR(GetSectionStatus))
{
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &sfsHandleCount, &sfsHandleBuffer);
for (index = 0; index < (int)sfsHandleCount; index++)
{
fs = NULL;
OpenedFileHandle = NULL;
Root = NULL;
Status = gBS->HandleProtocol(sfsHandleBuffer[index], &gEfiSimpleFileSystemProtocolGuid, (VOID**)&fs);
if (EFI_ERROR(Status))
continue;
Status = fs->OpenVolume(fs, &Root);
Status = Root->Open(Root, &OpenedFileHandle, L"EFI\\Boot", EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(Status))
continue;
Status = Root->Open(Root, &OpenedFileHandle, L"file", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
if (!EFI_ERROR(Status)) //уже существует
Root->Delete(OpenedFileHandle);
Status = Root->Open(Root, &OpenedFileHandle, L"file", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
if (!EFI_ERROR(Status))
{
Status = Root->Write(OpenedFileHandle, &Size, Buffer);
AsciiPrint("WriteSt:%d; DevicePath:%s\r\n", Status, ConvertDevicePathToText(DevicePathFromHandle(sfsHandleBuffer[index]), TRUE, TRUE));
}
Status = Root->Close(OpenedFileHandle);
}
}
if (Buffer != NULL)
FreePool(Buffer);
return EFI_SUCCESS;
}
Getting all handles that support FV2 protocol;
Processing all HOBs so number of handles that support FV2 protocol may increase;
For FV2 protocol i get count of handles and then get Volume names (device path for handle that support FV2 protocol) and files count: Here i can see that not all volumes are processd;
GetSectionFromAnyFv(*) then not interresting part and last saving file using simple file system protocol.

Related

PDFium: reading values of form fields?

How to parse form using PDFium, obtaining values of text fields, button statuses etc ?
I tried this code, but FPDFTextObj_GetText returns empty string.
ScopedFPDFTextPage pTextPage (FPDFText_LoadPage(Page));
for (int i = 0;i < FPDFPage_CountObjects(Page); i++)
{
FPDF_PAGEOBJECT pageObj = FPDFPage_GetObject(Page, i);
auto pageObjType = FPDFPageObj_GetType(pageObj);
if (pageObjType == FPDF_PAGEOBJ_TEXT)
{
auto size = FPDFTextObj_GetText(pageObj, pTextPage.get(), nullptr, 0);
std::vector<FPDF_WCHAR> buffer = GetFPDFWideStringBuffer(size);
size = FPDFTextObj_GetText(pageObj, pTextPage.get(), buffer.data(), size);
}
else if (pageObjType == FPDF_PAGEOBJ_FORM)
{
for (int j = 0; j < FPDFFormObj_CountObjects(pageObj); j++)
{
auto formObj = FPDFFormObj_GetObject(pageObj, j);
auto formObjType = FPDFPageObj_GetType(formObj);
if (formObjType == FPDF_PAGEOBJ_TEXT)
{
auto size = FPDFTextObj_GetText(pageObj, pTextPage.get(), nullptr, 0);
std::vector<FPDF_WCHAR> buffer = GetFPDFWideStringBuffer(size);
size = FPDFTextObj_GetText(pageObj, pTextPage.get(), buffer.data(), size);
}
}
}
}

DOCX4J conditional paragaph update merge FieldUpdater Does not work

Using a legacy IF field code:
enter image description here
and content controls:
private static byte[] mergingDocxFileWithXml(File file, File fileXml) {WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(file)
MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart()
ArrayList<String> datas
List<Object> contentControls = ContentControl.getAllContentControl(mainDocumentPart)
List<String> arrayListXpathToBoucle = new ArrayList<>()
for (Object contenControl : contentControls) {
ContentControl cControl = new ContentControl(contenControl)
String xPath = cControl.getXPath()
String title = cControl.getTitle()
if (xPath != null) {
datas = XmlPath.getXmlDataFrom(fileXml, xPath)
}
switch (title) {
case "DateDuJour":
cControl.setValue(getDateDay())
break
case "checkbox":
String checkValue = new String(Character.toChars(0x2612))
if (datas[0] != "1") {
checkValue = new String(Character.toChars(0x2610))
}
cControl.setValue(checkValue)
break
case "Boucle_Ligne":
xPath = cControl.getTag()
int indexBoucleContent = getIndexContentBoucle(wordMLPackage.mainDocumentPart.getContent(), xPath)
NodeList nodeList = XmlPath.getNodeListXmlFile(fileXml, xPath)
List<String> dataXpath = getAllXpathForBoucle(contentControls, xPath)
for (int i = 0; i < dataXpath.stream().count(); i++) {
arrayListXpathToBoucle.add(dataXpath.get(i))
}
int totalNode = nodeList.getLength()
for (int j = 0; j < totalNode; j++) {
wordMLPackage = mapingDataNode(j, cControl, contentControls, fileXml, dataXpath, wordMLPackage, indexBoucleContent, null, 0)
}
wordMLPackage.mainDocumentPart.getContent().remove(indexBoucleContent)
break;
case "Boucle_Colonne":
xPath = cControl.getTag()
NodeList nodeList = XmlPath.getNodeListXmlFile(fileXml, xPath)
List<String> dataXpath = getAllXpathForBoucle(contentControls, xPath)
int totalNode = nodeList.getLength()
for (int i = 0; i < dataXpath.stream().count(); i++) {
arrayListXpathToBoucle.add(dataXpath.get(i))
}
String boucleValue = ""
for (int i = 0; i < totalNode; i++) {
datas = XmlPath.getXmlDataFrom(fileXml, dataXpath.get(0))
boucleValue += datas.get(i) + ", "
}
boucleValue = boucleValue.substring(0, boucleValue.length() - 2)
addValueInContentControl(contentControls, dataXpath.get(0), 0, boucleValue, null, wordMLPackage)
break
case "Boucle_Ligne_Table":
xPath = cControl.getTag()
NodeList nodeList = XmlPath.getNodeListXmlFile(fileXml, xPath)
int indexBoucleContent = getIndexContentBoucle(wordMLPackage.mainDocumentPart.getContent(), xPath)
List<String> dataXpath = getAllXpathForBoucle(contentControls, xPath)
int totalNode = nodeList.getLength()
for (int i = 0; i < dataXpath.stream().count(); i++) {
arrayListXpathToBoucle.add(dataXpath.get(i))
}
int nodeIndex = 0
Tbl arraysBoucle = getArraysBoucle(wordMLPackage, indexBoucleContent)
Tr trContent
for (int i = 0; i < totalNode; i++) {
nodeIndex = i + 1
if (arraysBoucle.getContent().stream().count() > 1) {
trContent = WoeDocx4jFunction.getTr(arraysBoucle.getContent().get(1))
} else {
trContent = WoeDocx4jFunction.getTr(arraysBoucle.getContent().get(0))
}
wordMLPackage = mapingDataNode(i, cControl, contentControls, fileXml, dataXpath, wordMLPackage, indexBoucleContent, trContent, nodeIndex)
}
int lastIndexTr = wordMLPackage.getMainDocumentPart().getContent().get(indexBoucleContent).sdtContent.content.get(1).value.content.stream().count()
wordMLPackage.getMainDocumentPart().getContent().get(indexBoucleContent).sdtContent.content.get(1).value.content.remove(lastIndexTr - 1)
break
case "IMAGE":
datas = XmlPath.getXmlDataFrom(fileXml, xPath)
byte[] imageByte = base64ToImage(datas.get(0))
Inline inlineImage = newImage(wordMLPackage, imageByte)
cControl.setValue(null, inlineImage)
break
default:
String xpathBoucle = arrayListXpathToBoucle.find { it.startsWith(xPath) }
if (xpathBoucle != xPath) {
addValueInContentControl(contentControls, xPath, 0, "", fileXml,wordMLPackage)
}
break
}
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
wordMLPackage= mergingFieldWordMlPackage(wordMLPackage)
FieldUpdater updater = new FieldUpdater(wordMLPackage)
updater.update(true);
wordMLPackage.save(outputStream);
return outputStream.toByteArray();
}
Docx4j's legacy field processing does not parse IF fields: http://webapp.docx4java.org/OnlineDemo/ecma376/WordML/IF.html
If you need to do that, you'll need to write code to do the parsing.
An alternative would be to use OpenDoPE conditional content controls. With one of these, the content of the SDT is included only if the associated XPath evaluates to true.

recvfrom() socket is not working after this function

I am facing issue with calling to recvfrom function:
recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen);
Until this all functions are working.
Please let me know where I am making mistake. Should I use bind or not, or any mistake from this.
Output:
before sockname
after sockname
after sock
after setsockopt
after Bind
before recvfrom
My code:
struct sockaddr_can sockname = {
.can_family = AF_CAN,
.can_addr.j1939 = {
.addr = J1939_NO_ADDR,
.name = J1939_NO_NAME,
.pgn = J1939_NO_PGN,
},
}, peername = {
.can_family = AF_CAN,
.can_addr.j1939 = {
.addr = J1939_NO_ADDR,
.name = J1939_NO_NAME,
.pgn = J1939_NO_PGN,
},
};
uint8_t dat[128];
int valid_peername = 0;
unsigned int todo_send = 0;
int todo_recv = 0, todo_echo = 0, todo_prio = -1;
int todo_connect = 0, todo_names = 0, todo_wait = 0, todo_rebind = 0;
int todo_broadcast = 0, todo_promisc = 0;
int no_bind = 0,i;
printf("before sockname\n");
sockname.can_ifindex = if_nametoindex(CAN_SOCKET_NAME);
printf("after sockname\n");
sock = socket(PF_CAN, SOCK_DGRAM, CAN_J1939);
printf("after sock\n");
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &todo_broadcast, sizeof(todo_broadcast));
printf("after setsockopt\n");
ret = bind(sock, (void *)&sockname, sizeof(sockname));
if (ret < 0)
err(1, "bind()");
printf("after Bind\n");
while(1){
peernamelen = sizeof(peername);
printf("before recvfrom\n");
recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen);
printf("%02x %05x:", peername.can_addr.j1939.addr, peername.can_addr.j1939.pgn);
for (i = 0, j = 0; i < ret; ++i, j++) {
if (j == 8) {
printf("\n%05x ", i);
j = 0;
}
printf(" %02x", dat[i]);
}
printf("\n");
}
Please help me to solve this issue.

Sending messages through LoRaWAN using STM32

How do I send the messages through LoRaWAN?
static void PrepareTxFrame( uint8_t port )
{
switch( port ) {
case 10: {
int pos = 0;
pc.printf("Prepare message\n");
#if 0
uint32_t tempValue = ( uint32_t )( LightValue * 1000000.0 );
AppData[0] = LightMode;
AppData[1] = ( ( tempValue & 0xFF000000 ) >> 24 ) & 0xFF;
AppData[2] = ( ( tempValue & 0x00FF0000 ) >> 16 ) & 0xFF;
AppData[3] = ( ( tempValue & 0x0000FF00 ) >> 8 ) & 0xFF;
AppData[4] = ( tempValue & 0x000000FF );
#else
AppData[pos] = count;
pc.printf("\n\r");
pc.printf("The value of the counter is : %d", count);
count++;
pc.printf("\n\r");
time_t seconds = time(NULL);
printf("The time is %s", ctime(&seconds));
AppData[++pos] = seconds;
pc.printf("%d \n %d", AppData[0], AppData[1]);
pc.printf("\n\r");
#endif
pc.printf("Message Ready\n");
}
break;
case 15: {
int pos = 0;
AppData[pos++] = AppLedStateOn;
#if 0
if( IsTxConfirmed == true )
{
AppData[pos++] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
AppData[pos++] = LoRaMacDownlinkStatus.DownlinkCounter;
AppData[pos++] = LoRaMacDownlinkStatus.Rssi >> 8;
AppData[pos++] = LoRaMacDownlinkStatus.Rssi;
AppData[pos++] = LoRaMacDownlinkStatus.Snr;
}
#endif
AppDataSize = pos;
}
break;
case 224:
if( ComplianceTest.LinkCheck == true ) {
ComplianceTest.LinkCheck = false;
AppDataSize = 3;
AppData[0] = 5;
AppData[1] = ComplianceTest.DemodMargin;
AppData[2] = ComplianceTest.NbGateways;
ComplianceTest.State = 1;
} else {
switch( ComplianceTest.State ) {
case 4:
ComplianceTest.State = 1;
break;
case 1:
AppDataSize = 2;
AppData[0] = ComplianceTest.DownLinkCounter >> 8;
AppData[1] = ComplianceTest.DownLinkCounter;
break;
}
}
break;
default:
break;
}
}
/*!
* \brief
*
* Prepares the pay-load of the frame
*
* \retval [0: frame could be send, 1: error]
*/
static bool SendFrame( void )
{
McpsReq_t mcpsReq;
LoRaMacTxInfo_t txInfo;
if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
{
// Send empty frame in order to flush MAC commands
mcpsReq.Type = MCPS_UNCONFIRMED;
mcpsReq.Req.Unconfirmed.fBuffer = NULL;
mcpsReq.Req.Unconfirmed.fBufferSize = 0;
mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
LoRaMacUplinkStatus.Acked = false;
LoRaMacUplinkStatus.Port = 0;
LoRaMacUplinkStatus.Buffer = NULL;
LoRaMacUplinkStatus.BufferSize = 0;
SerialDisplayUpdateFrameType( false );
} else {
LoRaMacUplinkStatus.Acked = false;
LoRaMacUplinkStatus.Port = AppPort;
LoRaMacUplinkStatus.Buffer = AppData;
LoRaMacUplinkStatus.BufferSize = AppDataSize;
SerialDisplayUpdateFrameType( IsTxConfirmed );
if( IsTxConfirmed == false ) {
mcpsReq.Type = MCPS_UNCONFIRMED;
mcpsReq.Req.Unconfirmed.fPort = AppPort;
mcpsReq.Req.Unconfirmed.fBuffer = AppData;
mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
} else {
mcpsReq.Type = MCPS_CONFIRMED;
mcpsReq.Req.Confirmed.fPort = AppPort;
mcpsReq.Req.Confirmed.fBuffer = AppData;
mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
mcpsReq.Req.Confirmed.NbTrials = 8;
mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
}
}
if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) {
return false;
}
return true;
}
Will the counter data and the time be sent? Also is the data in AppData the ones to be transmitted? I want the count and the timestamp to be sent every time the LoRa device transmits.
The payload to send (AppData) is given to the LoRaMAC layer through the MCPS (MAC Common Part Sublayer) request, e.g. for an unconfirmed frame:
mcpsReq.Req.Unconfirmed.fBuffer = AppData;
So physically (i.e. by RF), AppData is sent but it's encrypted and encapsulated before.
PrepareFrame() function builds the frame to send according to the PHYPayload scheme (See the "MAC Message Formats" part in the LoRaWAN™ Specification 1.0.2 document), following these fields:
MHDR (1 byte) Mac header
DevAddr (4 bytes) Address of the end-device
FCtrl (1 byte) Frame control
FCnt (2 bytes) Frame counter
FOpts (0 - 15 bytes) Frame options
FPort (0 - 1 byte) Port field
FRMPayload (0 - N bytes) MAC Frame Payload Encryption, your AppData encrypted
MIC (4 bytes) Message Integrity Code
FRMPayload is encrypted according to FPort. The encryption algorithm is based on AES 128.
If FPort = [1..255], the AppSKey key will be used to encrypt your payload.
Else (FPort = 0), it's encrypted by using the NwkSKey key.
See the LoRaMacPayloadEncrypt() function for more details.
PHYPayload will be encapsulated by the Radio PHY Layer and sent through RF.

IOCP not getting triggered

I have writen an IOCP program and I am testing it through VPN.
It was all working OK, but then the server disconnected and the client GetQueuedCompletionStatus didn't trigger an exception.
I waited for one day,cbut it didn't get better. When I changed to a new VPN, the problem was solved, and I didn't get that problem later.
What's wrong? Has anybody seen the same problem before?
enter code here
enter code here
#include "XYTransport.h"
//---------------------------------------------------------------------------
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
//---------------------------------------------------------------------------
#define XYTCP_LIST_CLIENT0 0
#define XYTCP_LIST_CLIENT1 1
//---------------------------------------------------------------------------
#define XYTRANSPORT_TYPE_TCP_OPEN 0
#define XYTRANSPORT_TYPE_TCP_RECV 1
#define XYTRANSPORT_TYPE_TCP_SEND 2
//---------------------------------------------------------------------------
typedef struct tagXYOVERLAPPED
{
OVERLAPPED o;
SOCKET s;
UINT flags;
WSABUF wb;
}XYOVERLAPPED, *PXYOVERLAPPED;
//---------------------------------------------------------------------------
inline LPVOID XYAlloc(HANDLE heap, UINT size)
{
return(HeapAlloc(heap, 0, size));
}
inline VOID XYFree(HANDLE heap, LPVOID lpdata)
{
HeapFree(heap, 0, lpdata);
}
inline PXYOVERLAPPED XYOverlappedPop(PXYTRANSPORT pt, LPBYTE buffer, SOCKET s)
{
PXYOVERLAPPED pto = NULL;
SOCKADDR_IN name;
if (buffer == NULL)
{
buffer = (LPBYTE)VirtualAlloc(NULL, pt->bufferlength, MEM_COMMIT, PAGE_READWRITE);
}
if (buffer != NULL)
{
pto = (PXYOVERLAPPED)MALLOC(sizeof(XYOVERLAPPED));
if (pto != NULL)
{
pto->wb.buf = (char *)buffer;
pto->wb.len = pt->bufferlength;
if (s == INVALID_SOCKET)
{
pto->s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
if (pto->s != INVALID_SOCKET)
{
ZeroMemory(&name, sizeof(name));
name.sin_family = AF_INET;
name.sin_addr.S_un.S_addr = INADDR_ANY;
//name.sin_port = fn_htons(0);
name.sin_port = 0;
if (bind(pto->s, (const SOCKADDR *)&name, sizeof(name)) == 0)
{
if (CreateIoCompletionPort((HANDLE)pto->s, pt->hcompletion, (ULONG_PTR)pto->s, 0) == pt->hcompletion)
{
//
}
}
}
}
else
{
pto->s = s;
}
}
}
return(pto);
}
BOOL XYTCPPushReceive(PXYTRANSPORT pt, PXYOVERLAPPED pto, SOCKET s)
{
DWORD numberofbytes;
DWORD flags = 0;
BOOL result;
int error;
if (pto == NULL)
{
pto = XYOverlappedPop(pt, NULL, s);
}
ZeroMemory(&pto->o, sizeof(OVERLAPPED));
pto->flags = XYTRANSPORT_TYPE_TCP_RECV;
result = WSARecv(pto->s, &pto->wb, 1, &numberofbytes, &flags, &pto->o, NULL) != SOCKET_ERROR;
if (!result)
{
error = WSAGetLastError();
result = error == WSA_IO_PENDING;
if (!result)
{
printf("WSARecv\n");
}
}
return(result);
}
inline BOOL XYTCPPushSend(PXYTRANSPORT pt, PXYOVERLAPPED pto)
{
DWORD numberofbytes;
ULONG flags = MSG_PARTIAL;
BOOL result;
int error;
ZeroMemory(&pto->o, sizeof(OVERLAPPED));
pto->flags = XYTRANSPORT_TYPE_TCP_SEND;
//
pto->wb.len = 1024;
//
result = WSASend(pto->s, &pto->wb, 1, &numberofbytes, flags, &pto->o, NULL) != SOCKET_ERROR;
if (!result)
{
error = WSAGetLastError();
result = error == WSA_IO_PENDING;
if (!result)
{
printf("Send Error\n");
}
}
return(result);
}
DWORD WINAPI XYTransportWorkProc(LPVOID parameter)
{
PXYTRANSPORT pt = (PXYTRANSPORT)parameter;
HANDLE hcompletion = pt->hcompletion;
LPOVERLAPPED po;
PXYOVERLAPPED pto;
ULONG_PTR completionkey;
DWORD numberofbytes;
SOCKET s;
BOOL flag;
UINT type;
UINT count;
UINT error;
while(pt->working)
{
flag = GetQueuedCompletionStatus(hcompletion, &numberofbytes, &completionkey, &po, INFINITE);
if (po != NULL)
{
pto = (PXYOVERLAPPED)CONTAINING_RECORD(po, XYOVERLAPPED, o);
s = (SOCKET)completionkey;
type = pto->flags;
if (!flag)
{
//OutputDebugValue(_T("Except Error"), type, numberofbytes);
printf("Except Error %d\n", type);
}
if (numberofbytes == 0)
{
//OutputDebugValue(_T("Length Error"), type);
printf("Length Error %d\n", type);
}
if (!flag)
{
numberofbytes = 0;
}
switch (type)
{
case XYTRANSPORT_TYPE_TCP_OPEN:
if (flag)
{
setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
XYTCPPushSend(pt, pto);
printf("connected\n");
if (!XYTCPPushReceive(pt, NULL, s))
{
//
}
else
{
printf("post recv\n");
}
break;
}
break;
case XYTRANSPORT_TYPE_TCP_RECV:
if (numberofbytes > 0)
{
XYTCPPushReceive(pt, pto, s);
//OutputDebugString(_T("Recv"));
printf("Recv %d\n", numberofbytes);
}
else
{
printf("Recv Error\n");
}
break;
case XYTRANSPORT_TYPE_TCP_SEND:
if (numberofbytes > 0)
{
XYTCPPushSend(pt, pto);
printf("Send %d\n", numberofbytes);
}
else
{
printf("Send Except\n");
}
break;
default:
break;
}
}
else
{
printf("Quit %d, %d", GetCurrentThreadId(), flag);
break;
}
}
return(0);
}
VOID XYTransportStartup(PXYTRANSPORT pt, UINT pagesize)
{
pt->hcompletion = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (pt->hcompletion != INVALID_HANDLE_VALUE)
{
pt->lpfnConnectEx = NULL;
pt->bufferlength = pagesize;
pt->working = TRUE;
pt->hthread = CreateThread(NULL, 0, XYTransportWorkProc, (LPVOID)pt, 0, NULL);
}
}
BOOL XYTCPConnect(PXYTRANSPORT pt, const CHAR *host, USHORT port)
{
GUID id = WSAID_CONNECTEX;
DWORD numberofbytes = 0;
PXYOVERLAPPED pto;
SOCKADDR_IN name;
BOOL result = FALSE;
int error;
pto = XYOverlappedPop(pt, NULL, INVALID_SOCKET);
if (pt->lpfnConnectEx != NULL || WSAIoctl(pto->s, SIO_GET_EXTENSION_FUNCTION_POINTER, &id, sizeof(id), &pt->lpfnConnectEx, sizeof(pt->lpfnConnectEx), &numberofbytes, NULL, NULL) != SOCKET_ERROR)
{
ZeroMemory(&pto->o, sizeof(OVERLAPPED));
pto->flags = XYTRANSPORT_TYPE_TCP_OPEN;
ZeroMemory(&name, sizeof(name));
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.S_un.S_addr = inet_addr(host);
if (name.sin_addr.S_un.S_addr != INADDR_NONE)
{
numberofbytes = 0;
result = pt->lpfnConnectEx(pto->s, (SOCKADDR *)&name, sizeof(name), NULL, 0, &numberofbytes, &pto->o);
if(!result)
{
error = WSAGetLastError();
result = error == ERROR_IO_PENDING;
if (!result)
{
printf("ConnectEx error\n");
}
}
}
}
return(result);
}
//---------------------------------------------------------------------------
the client Thrown an exception is what i desired,so i can know.
I am using C language to write. Under normal circumstances, disconnect one end and the other end will trigger an exception, but I have found that sometimes have to wait a very long time, at least I'm waiting for more than one day are not triggered, and sometimes even in the off time can continue to deliver WSASend success for some time.