Copy TCHAR* string from other thread - c

I want to copy data from another thread to struct and print. _tpintf() doesnt show russian letters corret.
in concole I see this, but I expect to see "IN THREAD текст клиент1". Please explain why tchar doesnt work? Also I noticed that if I use _tcprintf, "клиент1" shows correct, but "текст" become wrong
Code of thread function which tries to copy data from another
static DWORD WINAPI StdinInfo(LPVOID param)
{
struct msg msg;
TCHAR buf[1280] = { 0 };
parameters* p = (parameters*)param;
while (TRUE)
{
_fgetts(buf, 1280, stdin);
while (_tcslen(buf) > 0 && buf[_tcslen(buf) - 1] == TEXT('\n'))
buf[_tcslen(buf) - 1] = TEXT('\0');
buf[128] = TEXT('\0');
if (!_tcscmp(buf, TEXT("stop")))
{
//printf("Terminating...\n");
msg.isEmpty = 0;
msg.type = STOP;
_tcscpy(msg.message, buf);
_tcscpy(msg.nickName, p->nickName);
SendMessage(p, &msg);
break;
}
else if (!_tcscmp(buf, TEXT("exit")))
{
msg.isEmpty = 0;
msg.type = DISCONNECT;
_tcscpy(msg.message, buf);
_tcscpy(msg.nickName, p->nickName);
SendMessage(p, &msg);
break;
}
msg.isEmpty = 0;
msg.type = MESSAGE;
_tcscpy(msg.message, buf);
_tcscpy(msg.nickName, p->nickName);
_tprintf(TEXT(" IN TREAD %s %s\n"), msg.message, p->nickName);
SendMessage(p, &msg);
}
return 0;
}

Related

wlan compiled code returns error and i need to specify the password for the ssid

I have this code right here I am using mingw to compile and I am running windows XP. When I run the output executable it gives me error prompt about the application..
Do I set everything correctly ? How do I set the SSID password for it to connect ? Also I want to know if I am using the correct network interface to connect (I have an external wifi adapter)..
I got the code from this link any help is very much appreciated..
//#define _WIN32_DCOM
#define _WIN32_WINNT 0x0600
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <objbase.h>
#include <rpcsal.h>
#include <objbase.h>
#include <wlanapi.h>
int main(){
PDOT11_SSID pSsid;
strcpy(pSsid->ucSSID, "SUPERONLINE-WiFi_24811");
pSsid->uSSIDLength = 25;
HANDLE wlanHandle;
unsigned long nv;
WlanOpenHandle(1, NULL, &nv, &wlanHandle);
DWORD dwResult = 0;
WLAN_CONNECTION_PARAMETERS cp;
memset(&cp, 0, sizeof(WLAN_CONNECTION_PARAMETERS));
cp.wlanConnectionMode = wlan_connection_mode_profile;
cp.strProfile = NULL;
cp.dwFlags = 0;
cp.pDot11Ssid = pSsid;
cp.pDesiredBssidList = 0;
cp.dot11BssType = dot11_BSS_type_any;
PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
PWLAN_INTERFACE_INFO pIfInfo = NULL;
// only use the first wifi interface
dwResult = WlanEnumInterfaces(wlanHandle, NULL, &pIfList);
pIfInfo = (WLAN_INTERFACE_INFO *)&pIfList->InterfaceInfo[1];
if (dwResult == ERROR_SUCCESS)
{
dwResult = WlanConnect(wlanHandle, &(pIfInfo->InterfaceGuid), &cp, NULL);
if (dwResult == ERROR_SUCCESS)
{
printf("Connected..\n");
//connected = true;
}
}
return 0;
}
This is the error I get:
Edit: I have made it this far to the code below.. But still I can not assign the value to PDOT11_SSID struct.. It seems the struct has UCHAR array yet I can't assign.. Here is the link
PDOT11_SSID pSsid;
UCHAR arr[22] = { 0 };
//memset(pSsid->ucSSID, '\0', 32); //this causes the same error too
memcpy(
arr,
(unsigned char[]){ 'S','U','P','E','R','O','N','L','I','N','E','-','W','i','F','i','_','2','4','8','1','1' },
sizeof(arr)); //memcpy to arr struct works..
ULONG len = 22;
pSsid->uSSIDLength = len;
memcpy(pSsid->ucSSID, arr, sizeof(arr)); // this line fails still..
Edit: I ran with -Wall -Wextra -pedantic -Werror Like David mentioned and with the code segment below:
PDOT11_SSID pSsid;
memset(pSsid->ucSSID, '\0', 32); //fails
I got this error
yet if I initialized with
PDOT11_SSID pSsid = { 0 };
or
PDOT11_SSID pSsid = NULL;
It compiled but I got the crash image above I used to get.. Important to note that memset(pSsid->ucSSID, '\0', 32); causes the crash as well. I can know this by commenting out each line and compiling/running again.
This is a burden since I am yet to figure out how to add SSID password with wlanapi.h so help for these will be much appreciated for me to move on forward.
Fyi: I use basic gcc to compile gcc.exe wlan.c -lwlanapi. If there is any working solution code to connect to an ssid with the ssid and password using wlanapi, a link to that is also appreciated.
Wlan connect from msdn is this link.. I can't see any security parameters, how do I set the password of the SSID I want to connect to ?
Here is what you have been looking for:
#include <winsock2.h>
#include <Wlanapi.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma warning(disable:4996) /*fuss sprintf*/
#define SSID_MAX_LEN (32)
int ConnectToTargetWifiSSID(char *pSSIDName, char *pPassword)
{
DWORD dwVersion;
#if(0)
DWORD dwMajorVersion;
dwVersion = 0 = dwMajorVersion;
dwVersion = GetVersion();
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
DWORD dwClientVersion;
dwClientVersion = ( dwMajorVersion >= 6) ? 2 : 1 ; /*vista or latter*/
#endif
DWORD result;
HANDLE iWifiHandle;
PWLAN_INTERFACE_INFO_LIST iAvailableInterfaces;
PWLAN_AVAILABLE_NETWORK_LIST availableNetworkList;
GUID iInterfaceGuid;
int isHavingProfile;
char authentication[64];
char encryption[64];
int isOpenedAP;
unsigned int i;
unsigned int iii;
WLAN_CONNECTION_PARAMETERS connParam;
iWifiHandle = NULL;
iAvailableInterfaces = NULL;
availableNetworkList = NULL;
/*part zero : one a wlan handle*/
result = WlanOpenHandle(1,NULL,&dwVersion, &iWifiHandle);
if(NULL != iWifiHandle)
{
/*get wireless network card*/
result = WlanEnumInterfaces(iWifiHandle, NULL, &iAvailableInterfaces);
if(ERROR_SUCCESS == result && iAvailableInterfaces->dwNumberOfItems > 0)
{
/*chose the zeroth one*/
printf("InterFaceName: %ls",iAvailableInterfaces->InterfaceInfo[0].strInterfaceDescription);
iInterfaceGuid = iAvailableInterfaces->InterfaceInfo[0].InterfaceGuid;
}
else
{
/*no wireless card*/
result = -2;
goto Exit_ConnectToTargetSSID;
}
}
else
{
result = -1;
goto Exit_ConnectToTargetSSID;
}/*if NULL != iWifiHandle*/
/*part one: scan available wifi routers(SSID)*/
result= WlanGetAvailableNetworkList(iWifiHandle, &iInterfaceGuid,
0x00000001, NULL, &availableNetworkList);
//WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES, NULL, &availableNetworkList);
if(ERROR_SUCCESS != result)
return -3;
isHavingProfile = FALSE;
isOpenedAP = FALSE;
iii = -1;
memset(&authentication[0], 0, 64);
memset(&encryption[0], 0, 64);
if( 0 == availableNetworkList->dwNumberOfItems)
{
/*on wifi router has been found*/
result = -4;
goto Exit_ConnectToTargetSSID;
}/*if 0 < wifiList->dwNumberOfItems*/
for(i = 0; i < availableNetworkList->dwNumberOfItems; i++)
{
DWORD flag;
printf("SSID:\t\t\t%s\nSIGNAL:\t\t\t%d\n",
availableNetworkList->Network[i].dot11Ssid.ucSSID,
availableNetworkList->Network[i].wlanSignalQuality);
printf("SECURITY:\t\t");
switch(availableNetworkList->Network[i].dot11DefaultAuthAlgorithm)
{
case DOT11_AUTH_ALGO_80211_OPEN:
printf("OPEN\n");
break;
case DOT11_AUTH_ALGO_80211_SHARED_KEY:
printf("WEP\n");
break;
case DOT11_AUTH_ALGO_WPA:
case DOT11_AUTH_ALGO_WPA_PSK:
case DOT11_AUTH_ALGO_WPA_NONE:
printf("WPA\n");
break;
case DOT11_AUTH_ALGO_RSNA:
case DOT11_AUTH_ALGO_RSNA_PSK:
printf("WPA2\n");
break;
default:
printf("UNKNOWN\n");
break;
}
printf("encryption:\t\t");
switch(availableNetworkList->Network[i].dot11DefaultCipherAlgorithm)
{
case DOT11_CIPHER_ALGO_NONE:
printf("NONE\n");
break;
case DOT11_CIPHER_ALGO_WEP40:
printf("WEP40\n");
break;
case DOT11_CIPHER_ALGO_TKIP:
printf("TKIP\n");
break;
case DOT11_CIPHER_ALGO_WEP104:
printf("WEP104\n");
break;
case DOT11_CIPHER_ALGO_CCMP:
printf("CCMP\n");
break;
default:
printf("UNKNOWN\n");
break;
}/*switch*/
flag = availableNetworkList->Network[i].dwFlags;
if(flag & 0x00000001)
printf("\t NOTE : Current connecting\n");
if(flag & 0x00000002)
printf("\t NOTE : WLAN_AVAILABLE_NETWORK_HAS_PROFILE\n");
if(flag & 0x00000004)
printf("\t NOTE : WLAN_AVAILABLE_NETWORK_CONSOLE_USER_PROFILE\n");
/*if(flag & WLAN_AVAILABLE_NETWORK_CONNECTED)
printf("\t NOTE : Current connecting\n");
if(flag & WLAN_AVAILABLE_NETWORK_HAS_PROFILE)
printf("\t NOTE : WLAN_AVAILABLE_NETWORK_HAS_PROFILE\n");
if(flag & WLAN_AVAILABLE_NETWORK_CONSOLE_USER_PROFILE)
printf("\t NOTE : WLAN_AVAILABLE_NETWORK_CONSOLE_USER_PROFILE\n");*/
printf("\n");
}/*for */
/*part two: save target SSID propertis*/
for(i = 0; i < availableNetworkList->dwNumberOfItems; i++)
{
if(0 == strncmp(pSSIDName, (char*)availableNetworkList->Network[i].dot11Ssid.ucSSID , SSID_MAX_LEN))
{
//WLAN_AVAILABLE_NETWORK_CONNECTED
if( 0x00000001 & availableNetworkList->Network[i].dwFlags)
{
printf("%s is current connecting!!\n", pSSIDName);
result = 1;
goto Exit_ConnectToTargetSSID;
}/*if*/
iii = i;
if(0x00000002 & availableNetworkList->Network[i].dwFlags)
//if(WLAN_AVAILABLE_NETWORK_HAS_PROFILE & availableNetworkList->Network[i].dwFlags)
isHavingProfile = TRUE;
/*list the target SSID properties*/
switch(availableNetworkList->Network[i].dot11DefaultAuthAlgorithm)
{
case DOT11_AUTH_ALGO_80211_OPEN:
sprintf(&authentication[0], "OPEN");
break;
case DOT11_AUTH_ALGO_80211_SHARED_KEY:
sprintf(&authentication[0], "WEP");
break;
case DOT11_AUTH_ALGO_WPA:
case DOT11_AUTH_ALGO_WPA_PSK:
case DOT11_AUTH_ALGO_WPA_NONE:
sprintf(&authentication[0], "WPAPSK");
break;
case DOT11_AUTH_ALGO_RSNA:
case DOT11_AUTH_ALGO_RSNA_PSK:
sprintf(&authentication[0], "WPA2PSK");
break;
default:
sprintf(&authentication[0], "UNKNOWN");
break;
}/*switch dot11DefaultAuthAlgorithm*/
switch(availableNetworkList->Network[i].dot11DefaultCipherAlgorithm)
{
case DOT11_CIPHER_ALGO_NONE:
sprintf(&encryption[0], "NOEN");
break;
case DOT11_CIPHER_ALGO_TKIP:
sprintf(&encryption[0], "TKIP");
break;
case DOT11_CIPHER_ALGO_CCMP:
sprintf(&encryption[0], "AES");
break;
default:
sprintf(&encryption[0], "WEP");
break;
}/*/*switch dot11DefaultCipherAlgorithm*/
break;
}/*if 0 == strncmp(pSSIDName, (char*)availableNetworkList->Network[i].dot11Ssid.ucSSID , SSID_MAX_LEN)*/
}/*for i*/
if(-1 == iii)
{
/*target router could not found */
result = -5;
goto Exit_ConnectToTargetSSID;
}/*if */
/*part there, set XML profile*/
if(FALSE == isHavingProfile)
{
/*if current computer has never connected to target router..*/
wchar_t profileXMLUnicode[4096];
char buff[4096];
DWORD reasonCode;
char profileTemplateXML[] = "<?xml version=\"1.0\"?>" \
"<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">"\
" <name>%s</name>" \
" <SSIDConfig> " \
" <SSID>" \
" <name>%s</name>"\
" </SSID>"\
" </SSIDConfig>"\
" <connectionType>ESS</connectionType>"\
" <connectionMode>auto</connectionMode>"\
" <MSM>"\
" <security>"\
" <authEncryption>"\
" <authentication>%s</authentication>"\
" <encryption>%s</encryption>"\
" <useOneX>false</useOneX>"\
" </authEncryption>"\
" <sharedKey>"\
" <keyType>passPhrase</keyType>"\
" <protected>false</protected>"\
" <keyMaterial>%s</keyMaterial>"\
" </sharedKey>"\
" </security>" \
" </MSM>" \
"</WLANProfile>" ;
reasonCode = 0;
sprintf(buff, profileTemplateXML, availableNetworkList->Network[iii].dot11Ssid.ucSSID,
availableNetworkList->Network[iii].dot11Ssid.ucSSID,
&authentication[0], &encryption[0], pPassword);
/*Covert ansi to unicode*/
MultiByteToWideChar(CP_ACP, 0, &buff[0], -1, &profileXMLUnicode[0], 4096);
result = WlanSetProfile(iWifiHandle, &iInterfaceGuid, 0, &profileXMLUnicode[0],
NULL, TRUE, NULL, &reasonCode);
wprintf( L"%s", profileXMLUnicode);
if(ERROR_SUCCESS != result)
{
result = -6;
goto Exit_ConnectToTargetSSID;
}/*if */
}
else
{
/*if current computer had connected to target router, and remember who it is ...*/
DWORD dwFlags;
DWORD dwGrantedAccess;
LPWSTR xml;
result = WlanGetProfile(iWifiHandle, &iInterfaceGuid,
availableNetworkList->Network[iii].strProfileName, NULL, &xml ,&dwFlags,&dwGrantedAccess);
wprintf( L"%s", xml);
}/*if FASLSE == isHavingProfile*/
/*part four, connect to target ssid */
connParam.pDot11Ssid= NULL;
connParam.strProfile= availableNetworkList->Network[iii].strProfileName;
connParam.wlanConnectionMode = wlan_connection_mode_profile;
connParam.pDesiredBssidList=NULL;
connParam.dot11BssType= availableNetworkList->Network[iii].dot11BssType;
connParam.dwFlags = 0;
//wprintf( L"%s", &iInterfaceGuid,wifiList->Network[iii].strProfileName);
result = WlanConnect(iWifiHandle, &iInterfaceGuid, &connParam, NULL);
if(ERROR_SUCCESS != result)
result = -7;
Exit_ConnectToTargetSSID:
if(NULL != availableNetworkList)
WlanFreeMemory(availableNetworkList);
if(NULL != iAvailableInterfaces)
WlanFreeMemory(iAvailableInterfaces);
if(NULL != iWifiHandle)
WlanCloseHandle(iWifiHandle, NULL);
return result;
}/*ConnectToTargetWifiSSID*/
int main(int argc, char *argv[])
{
ConnectToTargetWifiSSID("SUPERONLINE-WiFi_24811", "pass123");
return 0;
}/*main*/

Items overriden in list from keyboard thread

[1]I'm having a problem with my keyboard input thread. I'm currently using fgets to read input from the keyboard and then store it to a list using List_add. Problem is, my program seems to just print the last character that I inputted instead of the different strings of messages.
UPDATE:
Code in keyboardinput Thread
#define MAX_LEN 258
static pthread_t keyboardThread;
static pthread_mutex_t *psharedMutex;
static List* pList;
void* inputFunction(void* unused){
printf("Enter message:\n");
while (1) {
char* messageAllocated;
messageAllocated = malloc(MAX_LEN);
if(messageAllocated != NULL) {
//Wait for user input
fgets(messageAllocated, MAX_LEN, stdin); // This is how C read something from keyboard
pthread_mutex_lock(psharedMutex);
{
List_add(pList, messageAllocated); // Add message to list for FCFS
}
pthread_mutex_unlock(psharedMutex);
if (messageAllocated[0] == '!' && messageAllocated[2] == '\0') {
break;
}
memset(messageAllocated, 0, MAX_LEN);
}
else {
printf("Malloc Failed.\n");
}
};
return NULL;
}
void KeyboardInput_init(List* myList, pthread_mutex_t *sharedMutex) {
psharedMutex = sharedMutex;
pList = myList;
pthread_create(&keyboardThread, NULL, inputFunction, NULL);
}
void KeyboardInput_shutdown() {
pthread_join(keyboardThread, NULL);
}
Code in main.c
int main(int argc, char** args) {
// Create 2 Lists for transmit and receive
//List listPool;
List* outboundList; // Used in keyboard and UDP sendto threads
List* inboundList; // Used in screen and UDP recvfrom threads
outboundList = List_create();
inboundList = List_create();
// Receive information for s-talk transmission (ports, machine names)
setUpSTalkApplication();
Printer_init();
Signaller_init();
Printer_waitForShutdown();
Signaller_shutdown();
// Startup Modules
Receiver_init("Message received on Port ", &sharedMutex, remoteMachineName, hostPort); // goes before keyboard
KeyboardInput_init(outboundList, &sharedMutex);
Sender_init(outboundList, &sharedMutex, &condVar, remoteMachineName, targetPort);
//ScreenOutput_init(inboundList, &condVar, &sharedMutex);
// Shutdown Modules
//ScreenOutput_shutdown();
KeyboardInput_shutdown();
Receiver_shutdown();
Sender_shutdown();
printf("Done.\n");
while(List_count(outboundList) != 0) {
char* x = List_trim(outboundList);
printf("%s", x);
};
return 0;
}
Firstly, You should validate the pointer messageAllocated after malloc and the sizeof(messageAllocated) is only 4 or 8 bytes, you should use MAX_LEN instead of sizeof(messageAllocated)
while (1) {
char * messageAllocated;
messageAllocated = malloc(MAX_LEN);
if(messageAllocated != NULL)
{
fgets(messageAllocated, MAX_LEN, stdin);
List_add(pList, messageAllocated)
if (messageAllocated[0] == '!') {
break;
}
//hope you are doing this before reading another string, or else there will be memory leak
free(messageAllocated); messageAllocated = NULL;
}
else
{
printf("malloc failed\n");
}
}

Sprintf_s giving me weird boxes instead of strings

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "resource.h"
char* getString(HWND hwnd,int dlgItem)
{
int len = GetWindowTextLength(GetDlgItem(hwnd, dlgItem));
if (len > 0)
{
TCHAR szBuffer[128] = { 0 };
int s = GetDlgItemText(hwnd, dlgItem, szBuffer, len + 1);
return szBuffer;
}
return "";
}
int getInt(HWND hwnd, int dlgItem)
{
int len = GetWindowTextLength(GetDlgItem(hwnd, dlgItem));
if (len > 0)
{
BOOL bsuccess;
int Number = GetDlgItemInt(hwnd, dlgItem, &bsuccess, FALSE);
return Number;
}
return 0;
}
char* _personRecord(HWND hwnd)
{
int nameLength = GetWindowTextLength(GetDlgItem(hwnd, txtName)) + 1;
int addressLength = GetWindowTextLength(GetDlgItem(hwnd, txtAddress)) + 1;
int phoneLength = GetWindowTextLength(GetDlgItem(hwnd, txtPhone)) + 1;
int emailLength = GetWindowTextLength(GetDlgItem(hwnd, txtEmail)) + 1;
char* name = malloc(nameLength);
name = getString(hwnd, txtName);
int age = getInt(hwnd, txtAge);
char* address = malloc(addressLength);
address = getString(hwnd, txtAddress);
int zip = getInt(hwnd, txtZip);
char* phone= malloc(phoneLength);
phone = getString(hwnd, txtPhone);
char* email = malloc(emailLength);
email = getString(hwnd, txtEmail);
int length = nameLength + addressLength + phoneLength + emailLength + age + zip;
char* personRecord = malloc(length);
sprintf_s(personRecord , length, "Name: %s\nAge: %d\nAddress: %s\nZip: %d\nPhone: %s\nEmail: %s\n", name, age, address, zip, phone, email);
OutputDebugString("\nStart*********\n");
OutputDebugString(personRecord);
OutputDebugString("\nEnd**********\n");
return personRecord;
free(name);
free(address);
free(phone);
free(email);
free(personRecord);
}
void saveFile(char* record)
{
FILE* fp = NULL;
if(fopen_s(&fp,"contacts.txt", "a") == 0)
{
fprintf(fp, "\n");
fprintf(fp, record);
fclose(fp);
}
else
{
OutputDebugString("Op failed");
}
}
//Works 100 percent.
void clear(HWND hwnd)
{
SetDlgItemText(hwnd, txtName, "");
SetDlgItemText(hwnd, txtAge, "");
SetDlgItemText(hwnd, txtAddress, "");
SetDlgItemText(hwnd, txtZip, "");
SetDlgItemText(hwnd, txtPhone, "");
SetDlgItemText(hwnd, txtEmail, "");
}
BOOL CALLBACK EventHandler(HWND holdWindow, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case btnSave:
saveFile(_personRecord(holdWindow));
clear(holdWindow);
break;
case btnLoad:
//print all records to console
break;
case btnClose:
EndDialog(holdWindow, 0);
}
break;
case WM_CLOSE:
EndDialog(holdWindow, 0);
break;
default:
return FALSE;
}
return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
return DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, EventHandler);
}
First real crack at a C program that really does anything of note. I'm sure I'm doing a ton wrong with memory management but I'm a newbie so please go easy on me. As far as my problem goes, sprintf is turning those strings into boxes when I print them out and save them to the file.
I thought it could be my getString methods that are causing this problem but if I print a variable out after it's been called it works fine in the debug.
I've tried adjusting how I'm allocation personRecord several times including making it static and NULL. I've also tried printing them individually.
I'm at a complete loss at this point.
char* szBuffer[1024] = { 0 };
TCHAR was the wrong type and 128 was not enough memory to save the string properly. I adjusted how much memory could be used and it fixed the issue. I think the correct answer would be to malloc the data to the length of the string I took from the window but I'm not sure entirely.
Thanks for everyone who posted.
char* getString(HWND hwnd,int dlgItem)
{
int len = GetWindowTextLength(GetDlgItem(hwnd, dlgItem));
if (len > 0)
{
char* record = malloc(len * sizeof *record + 1);
int s = GetDlgItemText(hwnd, dlgItem, record, len + 1);
return record;
free(record);
}
return "";
}

c programming optimize packet forwarder

I have written UDP packet forwarder which opens UDP port and it continuously listen on perticolar socket and when data comes to it, it forwards data to another end point.
Problem I am facing is while running process for longer duration its process eats up almost 50% of system memory and other process suffers from it.
I have use PCRE library for some regex checking but it seems like main cause of problem how can i optimize my code that can run for infinite without any memory issue.
below is my code i have use of PCRE regex and socket forwarder.
int parse(char *str){
pcre *reCompiled;
pcre_extra *pcreExtra;
int pcreExecRet;
int subStrVec[30];
const char *pcreErrorStr;
int pcreErrorOffset;
int returnval;
char *aStrRegex;
char **aLineToMatch;
const char *psubStrMatchStr;
int j;
//*aLineToMatch = str;
aStrRegex = "(.*)(\"ABC\":)(\\d+)+";
//printf("Regex to use: %s\n", aStrRegex);
// First, the regex string must be compiled.
reCompiled = pcre_compile(aStrRegex, 0, &pcreErrorStr, &pcreErrorOffset, NULL);
/* OPTIONS (second argument) (||'ed together) can be:
PCRE_ANCHORED -- Like adding ^ at start of pattern.
PCRE_CASELESS -- Like m//i
PCRE_DOLLAR_ENDONLY -- Make $ match end of string regardless of \n's
No Perl equivalent.
PCRE_DOTALL -- Makes . match newlins too. Like m//s
PCRE_EXTENDED -- Like m//x
PCRE_EXTRA --
PCRE_MULTILINE -- Like m//m
PCRE_UNGREEDY -- Set quantifiers to be ungreedy. Individual quantifiers
may be set to be greedy if they are followed by "?".
PCRE_UTF8 -- Work with UTF8 strings.
*/
// pcre_compile returns NULL on error, and sets pcreErrorOffset & pcreErrorStr
if(reCompiled == NULL) {
printf("ERROR: Could not compile '%s': %s\n", aStrRegex, pcreErrorStr);
exit(1);
} /* end if */
// Optimize the regex
pcreExtra = pcre_study(reCompiled, 0, &pcreErrorStr);
/* pcre_study() returns NULL for both errors and when it can not optimize the regex. The last argument is how one checks for
errors (it is NULL if everything works, and points to an error string otherwise. */
if(pcreErrorStr != NULL) {
printf("ERROR: Could not study '%s': %s\n", aStrRegex, pcreErrorStr);
exit(1);
}
/* Try to find the regex in aLineToMatch, and report results. */
pcreExecRet = pcre_exec(reCompiled,
pcreExtra,
str,
strlen(str), // length of string
0, // Start looking at this point
0, // OPTIONS
subStrVec,
30); // Length of subStrVec
/* pcre_exec OPTIONS (||'ed together) can be:
PCRE_ANCHORED -- can be turned on at this time.
PCRE_NOTBOL
PCRE_NOTEOL
PCRE_NOTEMPTY */
// Report what happened in the pcre_exec call..
//printf("pcre_exec return: %d\n", pcreExecRet);
if(pcreExecRet < 0) { // Something bad happened..
returnval = -1;
switch(pcreExecRet) {
case PCRE_ERROR_NOMATCH : log_message("String did not match the pattern"); break;
case PCRE_ERROR_NULL : log_message("Something was null"); break;
case PCRE_ERROR_BADOPTION : log_message("A bad option was passed"); break;
case PCRE_ERROR_BADMAGIC : log_message("Magic number bad (compiled re corrupt?)"); break;
case PCRE_ERROR_UNKNOWN_NODE : log_message("Something kooky in the compiled re"); break;
case PCRE_ERROR_NOMEMORY : log_message("Ran out of memory"); break;
default : log_message("Unknown error"); break;
} /* end switch */
} else {
//printf("Result: We have a match!\n");
// At this point, rc contains the number of substring matches found...
if(pcreExecRet == 0) {
pcreExecRet = 30 / 3;
} /* end if */
// PCRE contains a handy function to do the above for you:
for(j=0; j<pcreExecRet; j++) {
pcre_get_substring(str, subStrVec, pcreExecRet, j, &(psubStrMatchStr));
} /* end for */
returnval = atoi(psubStrMatchStr);
// Free up the substring
pcre_free_substring(psubStrMatchStr);
} /* end if/else */
// Free up the regular expression.
pcre_free(reCompiled);
// Free up the EXTRA PCRE value (may be NULL at this point)
if(pcreExtra != NULL) {
#ifdef PCRE_CONFIG_JIT
pcre_free_study(pcreExtra);
#else
pcre_free(pcreExtra);
#endif
}
return returnval;
}
-------------------Udp Listener---------------
while (1) {
n = recvfrom(sock_receiver,buf,2048,0,(struct sockaddr *)&from,&sender_length);
if (n < 0) error("recvfrom");
//write(1,"Received a datagram: ",21);
// printf("n = %d\n", n);
// printf("length of buffer = %lu\n", strlen(buf));
// write(1,buf,n);
strncpy(str, buf, n);
str[n] = '\0'; // IMPORTANT!
value = parse(str);
if(curTime != get_hour()){
//sprintf(temp_str,"Counter",minute,get_minute());
log_message("Counter reset");
reset_component_hits(components);
//reset_component_hits(dropped_msg);
curTime = get_hour();
}
if(value >=0 && components[value] < component_limit && value < max_component){
n = sendto(sock_forwarder,buf,n,0,(const struct sockaddr *)&sender,sender_length);
if (n < 0){
error("sendto");
}
components[value] = components[value]+1;
}else{
if(value < 0 ) {
error_msg = "Unable to parse component";
}else if(value >= max_component){
error_msg = "value not found in valid component list";
}else if(components[value] >= component_limit) {
error_msg = "Rate limit exceeded";
}else {
error_msg = "Message dropped for Unknown reason";
}
sprintf(temp_str,"[Component:%d] %s",value,error_msg);
log_message(temp_str);
bzero(temp_str,100);
bzero(error_msg,100);
}
// print_array(components);
// print_array(dropped_msg);
bzero(buf,2048);
bzero(str,2048);
}

transferring from PLC (OPC client server Kepware) to MS Access, C

I am completely new to working with PLCs, but I have a project that need fetch data from an OPC client server, then send it to an Access database table. The bulk of the code minus OPCWriteGroupItems was from someone else. I am just lost on transferring the data that the get from OPCReadGroupItems to the proper variables in my function OPCWriteGroupItems. I just want to get the values that are read into the variables. Thanks.
F.Y.I.
My query statement I know needs to be tweaked so that it will read the variables correctly but that is anouther problem that I am working on. This is the more pressing concern.
Below are the two functions that I spoke of:
//---------------------------------------------------------
// Read items from an OPC Group
//---------------------------------------------------------
OPCStat OPCReadGroupItems (int iGrp, struct Var_Stru v[] )
{
HRESULT r1;
HRESULT *hr;
OPCITEMSTATE *is;
int iItem;
OPCStat RetVal=OPCSuccess;
if (pGRPTagSIO[iGrp]) {
if (bOPCDebug) printf("Reading data .... \n");
r1 = pGRPTagSIO[iGrp]->Read(OPC_DS_CACHE,
OPCDataGroup[iGrp].iNumItems,
OPCDataGroup[iGrp].hItem,
&is,
&hr);
if (FAILED(r1)) {
printf("Error from Read(%lx)\n", r1);
RetVal = OPCError;
} else {
// if the read worked then copy results to the v structure based on type
for (iItem=0;iItem<OPCDataGroup[iGrp].iNumItems;iItem++ ) {
//printf("Read item= %d, hr= %lx, Quality= %2x", iItem, hr[iItem], is[iItem].wQuality);
if(!FAILED(hr[iItem])) {
// printf("%d", is[iItem].vDataValue.vt);
//printf("%d", iGrp);
switch(is[iItem].vDataValue.vt) {
case VT_I2: // 2
v[iItem].iVal = is[iItem].vDataValue.iVal;
break;
case VT_I4: // 3
v[iItem].lVal = is[iItem].vDataValue.lVal;
break;
case VT_R4: // 4
// printf("Z");
v[iItem].fVal = is[iItem].vDataValue.fltVal;
break;
case VT_R8: // 5
v[iItem].dblVal = is[iItem].vDataValue.dblVal;
break;
case VT_BOOL: // 11
v[iItem].bVal = is[iItem].vDataValue.boolVal;
break;
case VT_UI1: // 11
printf("TEST");
sprintf(v[iItem].cVal, "%s", is[iItem].vDataValue.cVal);
printf("%s", v[iItem].cVal);
printf("%c", v[iItem].cVal);
break;
case VT_BSTR: // 8
// printf("TEST");
sprintf(v[iItem].cVal,"%-.*ls", kOPCStringSize,is[iItem].vDataValue.bstrVal );
//printf("\n STRING STRING %s \n", v[iItem].cVal);
break;
default:
break;
}
}
if(iGrp >= 0 && iGrp <=)
{
stuct_double[iGrp-1][iItem] = v[iItem].dblVal;
// printf("group %d ", iGrp);
// printf("Tag %i: %10.2f\n", iItem, root_plc[iItem]);
}
if(iGrp > 0 && iGrp <= 44)
{
struc_floats[iGrp-1][iItem] = v[iItem].fVal;
//printf("GROUP %d ", iGrp);
//printf("Tag %i: %10.2f\n", iItem, struc_floats[iGrp-1][iItem]);
}
else
{
printf("Error reading data item %d\n", iItem);
//RetVal=OPCError; //Make not as severe -- rjf 06/03/02
RetVal=OPCWarning;
//break; //Escape the for-loop -- rjf- 5/13/02
}
*/
pIMalloc->Free(hr);
for (iItem=0;iItem<OPCDataGroup[iGrp].iNumItems;iItem)
{
VariantClear($is[iItem].vdatavalue)
}
pIMalloc->Free(is);
}
}
else{
RetVal=OPCError;
}
return (RetVal);
}
//-----------------------------------------
// Write items contained in an OPC Group
//-----------------------------------------
OPCStat OPCWriteGroupItems (int iGrp, struct Var_Stru vOut[] )
{
/* Data Access Method used in this sample */
const char* DAM = "Direct ODBC";
/* Connection string for Direct ODBC */
char szDSN[256] = "DSN=Gas_Meter_check;";
HRESULT r1,r2;
HRESULT *hr;
VARIANT v[nMaxOPCItems];
int iItem;
OPCStat RetVal=OPCSuccess;
if (pGRPTagSIO[iGrp]) {
for (iItem=0;iItem<OPCDataGroup[iGrp].iNumItems;iItem++) {
v[iItem].vt = OPCDataGroup[iGrp].iType;
switch(OPCDataGroup[iGrp].iType) {
case VT_I2: // 2
v[iItem].iVal = vOut[iItem].iVal;
break;
case VT_I4: // 3
v[iItem].lVal = vOut[iItem].lVal;
break;
case VT_R4: // 4
v[iItem].fltVal = vOut[iItem].fVal;
break;
case VT_R8: // 5
v[iItem].dblVal = vOut[iItem].dblVal;
HENV hEnv; HDBC hDbc;
/* ODBC API return status */ RETCODE rc;
int iConnStrLength2Ptr;
char szConnStrOut[256];
int i= 0;
char datetime[256];
double HMCO=1.0;
double HMR,HMT;
unsigned char* InsertQuery = "INSERT INTO Data ( [Date / Time], [Hot Strip Mill rate], [Hot Strip Mill Comm Okay], [Hot Strip Mill Total] ) SELECT #datetime# AS Expr1, HMR AS Expr2, 1 AS Expr3, HMCO AS Expr4, HMT AS Expr5;";
SQLCHAR chval1[128], chval2[128], colName[128];
int ret1;
int ret2;
/* Number of rows and columns in result set */
SQLINTEGER rowCount = 0;
SQLSMALLINT fieldCount = 0, currentField = 0;
HSTMT hStmt;
/* Allocate an environment handle */
rc = SQLAllocEnv(&hEnv);
/* Allocate a connection handle */
rc = SQLAllocConnect(hEnv, &hDbc);
/* Connect to the TakeCharge database */
rc = SQLDriverConnect(hDbc, NULL, (unsigned char*)szDSN,
SQL_NTS, (unsigned char*)szConnStrOut,
255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc))
{
printf("%s: Successfully connected to database. Data source name: \n %s\n",
DAM, szConnStrOut);
/* Prepare SQL query */
printf("%s: SQL InsertQuery:\n %s\n", DAM, InsertQuery);
rc = SQLAllocStmt(hDbc,&hStmt);
rc = SQLPrepare(hStmt, InsertQuery, SQL_NTS);
/* Excecute the query and create a record set */
rc = SQLExecute(hStmt);
if (SQL_SUCCEEDED(rc))
{
printf("Executing query...");
printf("\n");
}
while (SQL_SUCCEEDED(rc))
{
printf(" insert passed\n");
rc = SQLFetch(hStmt);
rowCount++;
};
}
else
{
printf("%s: Couldn't connect to %s.\n", DAM, szDSN);
}
/* Disconnect*/
SQLDisconnect(hDbc);
printf("%s: Cleanup. Done.\n", DAM);
break;
case VT_BOOL: // 11
v[iItem].bVal = vOut[iItem].bVal;
break;
case VT_BSTR: // 8
// printf(" In Message value (VT_BSTR) = %s \n",vOut[iItem].cVal );
r2 = LPTSTR_to_BSTR ( &v[iItem].bstrVal , vOut[iItem].cVal);
if ( r2 != S_OK ) {
printf ("error in memory \n");
RetVal = OPCError;
}
// printf(" Write Msg value(VT_BSTR) = %ls \n", v[iItem].bstrVal );
report(0,0,0, "STRINGS data %s",vOut[iItem].cVal);
break;
default:
printf(" value(unknown type:%d) ", OPCDataGroup[iGrp].iType );
RetVal = OPCError;
break;
}
//if (bOPCDebug) DumpVariant(OPCDataGroup[iGrp].cTagNames[iItem], &v[iItem]);
}
r1 = pGRPTagSIO[iGrp]->Write(
OPCDataGroup[iGrp].iNumItems,
OPCDataGroup[iGrp].hItem,
v,
&hr);
if (FAILED(r1))
{
printf("Error from Write(%lx)\n", r1);
RetVal = OPCError;
} else {
//if (bOPCDebug) printf("Successful Write ... \n");
// Clear the Variant
for (iItem=0;iItem<OPCDataGroup[iGrp].iNumItems;iItem++) {
VariantClear(&v[iItem]);
}
pIMalloc->Free(hr);
}
} else {
RetVal = OPCError;
}
return(RetVal);
}
C/C++ is not my first language, and I am not familiar with your specific OPC library (there are so many), but according to my understanding of the code you are reading some kind of a variant variable, and with case statements you determine it's type and store it to proper property of v[iItem]. You repeat that in a loop for all tags in that group. There must be some property that tells you the name of the tag you have just read, and you can use it to solve the problem.
For example, if the current tag you are reading is of single float type, then this case section will be executed:
case VT_R4:
v[iItem].fVal = is[iItem].vDataValue.fltVal;
break;
So v[iItem].fVal contains the 4 bytes single float value of the OPC tag. If the current tag you are reading is of double float type, then this case section will be executed:
case VT_R8:
v[iItem].dblVal = is[iItem].vDataValue.dblVal;
break;
and v[iItem].dblVal contains the 8 bytes double float value of the OPC tag. I think you get the picture.
You should really spend some time with OPC DA tutorials on http://www.opcfoundation.org.

Resources