Imported gammu 0.90.7
[gammu.git] / win32 / dll / gammu.c
blob6e1bd5e68ba7417c8d0c77c2c534de722da1a00c
2 #include <windows.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <conio.h>
7 #include <process.h>
8 #include <ctype.h>
9 #include <locale.h>
10 #include <signal.h>
12 #include "../../common/gsmstate.h"
13 #include "../../common/gsmcomon.h"
14 #include "../../common/misc/coding/coding.h"
16 typedef struct {
17 GSM_StateMachine s;
18 void (**PhoneCallBack) (int x, int s, boolean connected);
19 void (**SecurityCallBack) (int x, int s, GSM_SecurityCodeType State);
20 void (**SMSCallBack) (int x, int s);
21 HANDLE hCommWatchThread;
22 DWORD dwThreadID;
23 HANDLE Mutex;
24 bool ThreadTerminate;
25 bool Used;
26 int number;
27 int errors;
28 GSM_SecurityCodeType SecurityStatus;
29 GSM_Error SendSMSStatus;
30 } GSM_StateMachineExt;
32 GSM_StateMachineExt s[10];
34 bool SetErrorCounter(int i, GSM_Error error)
36 switch (error) {
37 case GE_TIMEOUT:
38 s[i].errors++;
39 break;
40 case GE_NOTSUPPORTED:
41 case GE_NOTIMPLEMENTED:
42 break;
43 default:
44 if (s[i].errors > 0) s[i].errors--;
46 if (s[i].errors > 1) return true;
47 return false;
50 BOOL LoopProc(int *i)
52 GSM_Error error;
53 GSM_SecurityCodeType SecurityStatus;
54 GSM_SMSMemoryStatus SMSStatus;
55 void (*PhoneCall) (int x, int s, boolean connected);
56 void (*SecurityCall) (int x, int s, GSM_SecurityCodeType State);
57 void (*SMSCall) (int x, int s);
59 while(1) {
60 if (s[*i].errors > 1) {
61 if (s[*i].ThreadTerminate) break;
62 if (*s[*i].PhoneCallBack != NULL && s[*i].errors < 250) {
63 PhoneCall = *s[*i].PhoneCallBack;
64 PhoneCall(1,*i,false);
66 if (s[*i].errors != 250) {
67 WaitForSingleObject(s[*i].Mutex, INFINITE );
68 GSM_TerminateConnection(&s[*i].s);
69 ReleaseMutex(s[*i].Mutex);
71 s[*i].errors = 251;
72 if (s[*i].ThreadTerminate) break;
73 WaitForSingleObject(s[*i].Mutex, INFINITE );
74 error=GSM_InitConnection(&s[*i].s,2);
75 ReleaseMutex(s[*i].Mutex);
76 if (s[*i].ThreadTerminate) break;
77 // if (error == GE_DEVICEOPENERROR) break;
78 if (error == GE_NONE) {
79 s[*i].errors = 0;
80 if (*s[*i].PhoneCallBack != NULL) {
81 PhoneCall = *s[*i].PhoneCallBack;
82 PhoneCall(1,*i,true);
84 if (s[*i].ThreadTerminate) break;
85 WaitForSingleObject(s[*i].Mutex, INFINITE );
86 error=s[*i].s.Phone.Functions->SetAutoNetworkLogin(&s[*i].s);
87 ReleaseMutex(s[*i].Mutex);
88 SetErrorCounter(*i, error);
90 } else {
91 if (s[*i].ThreadTerminate) break;
92 if (*s[*i].SecurityCallBack != NULL) {
93 WaitForSingleObject(s[*i].Mutex, INFINITE );
94 error=s[*i].s.Phone.Functions->GetSecurityStatus(&s[*i].s,&SecurityStatus);
95 ReleaseMutex(s[*i].Mutex);
96 if (SetErrorCounter(*i, error)) continue;
97 switch (error) {
98 case GE_NONE:
99 if (s[*i].ThreadTerminate) break;
100 if (SecurityStatus != s[*i].SecurityStatus) {
101 if (*s[*i].SecurityCallBack != NULL) {
102 s[*i].SecurityStatus = SecurityStatus;
103 SecurityCall = *s[*i].SecurityCallBack;
104 SecurityCall(1,*i,SecurityStatus);
107 break;
108 case GE_NOTSUPPORTED:
109 if (s[*i].ThreadTerminate) break;
110 if (*s[*i].SecurityCallBack != NULL) {
111 SecurityStatus = 0;
112 s[*i].SecurityStatus = 0;
113 SecurityCall = *s[*i].SecurityCallBack;
114 SecurityCall(1,*i,SecurityStatus);
116 default:
117 break;
120 if (s[*i].ThreadTerminate) break;
121 if (*s[*i].SMSCallBack!=NULL) {
122 WaitForSingleObject(s[*i].Mutex, INFINITE );
123 error=s[*i].s.Phone.Functions->GetSMSStatus(&s[*i].s,&SMSStatus);
124 ReleaseMutex(s[*i].Mutex);
125 if (SetErrorCounter(*i, error)) continue;
126 if (s[*i].ThreadTerminate) break;
127 if (error == GE_NONE) {
128 if (SMSStatus.SIMUsed+SMSStatus.PhoneUsed != 0) {
129 SMSCall = *s[*i].SMSCallBack;
130 SMSCall(1,*i);
134 if (s[*i].ThreadTerminate) break;
135 my_sleep(200);
136 if (s[*i].ThreadTerminate) break;
140 s[*i].Used = false;
141 s[*i].hCommWatchThread = NULL;
142 s[*i].dwThreadID = 0;
144 return(TRUE);
147 static void CreatePhoneThread(int *phone,
148 void (**PhoneCallBack) (int x, int s, boolean connected),
149 void (**SecurityCallBack) (int x, int s, GSM_SecurityCodeType State),
150 void (**SMSCallBack) (int x, int s))
152 s[*phone].Mutex = CreateMutex( NULL, FALSE, NULL );
153 s[*phone].SecurityStatus = 0;
154 s[*phone].number = *phone;
156 s[*phone].PhoneCallBack = PhoneCallBack;
157 s[*phone].SecurityCallBack = SecurityCallBack;
158 s[*phone].SMSCallBack = SMSCallBack;
159 s[*phone].ThreadTerminate = false;
160 s[*phone].hCommWatchThread = CreateThread((LPSECURITY_ATTRIBUTES) NULL,
162 (LPTHREAD_START_ROUTINE) LoopProc,
163 (LPVOID) &s[*phone].number,
164 0, &s[*phone].dwThreadID);
167 static void CheckConnectionType(int *phone,
168 char *connection,
169 char *connection_to_check,
170 GSM_Error *error,
171 GSM_Error *error2,
172 void (**PhoneCallBack) (int x, int s, boolean connected),
173 void (**SecurityCallBack) (int x, int s, GSM_SecurityCodeType State),
174 void (**SMSCallBack) (int x, int s))
176 void (*PhoneCall) (int x, int s, boolean connected);
178 s[*phone].s.CurrentConfig->Connection = connection_to_check;
179 *error=GSM_InitConnection(&s[*phone].s,2);
180 switch (*error) {
181 case GE_NONE:
182 strcpy(connection,connection_to_check);
183 s[*phone].errors = 0;
184 CreatePhoneThread(phone,PhoneCallBack,SecurityCallBack,SMSCallBack);
185 if (*s[*phone].PhoneCallBack != NULL) {
186 PhoneCall = *s[*phone].PhoneCallBack;
187 PhoneCall(1,*phone,true);
189 case GE_DEVICEOPENERROR:
190 break;
191 default:
192 *error2 = GSM_TerminateConnection(&s[*phone].s);
196 GSM_Error WINAPI mystartconnection(int *phone,
197 char *device,
198 char *connection,
199 char *model,
200 char *logfile,
201 char *logfiletype,
202 void (**PhoneCallBack) (int x, int s, boolean connected),
203 void (**SecurityCallBack) (int x, int s, GSM_SecurityCodeType State),
204 void (**SMSCallBack) (int x, int s))
206 int i;
207 GSM_Error error,error2;
209 #ifndef WIN32
210 setlocale(LC_ALL, "");
211 #else
212 setlocale(LC_ALL, ".OCP");
213 #endif
215 *phone = 0;
216 for (i=1;i<10;i++) {
217 if (!s[i].Used) {
218 s[i].Used = true;
219 *phone = i;
220 break;
223 if (*phone == 0) return GE_MOREMEMORY;
225 s[*phone].s.ConfigNum = 1;
226 s[*phone].s.msg = NULL;
227 s[*phone].s.CurrentConfig = &s[*phone].s.Config[0];
228 s[*phone].s.CurrentConfig->Localize = "";
229 s[*phone].s.CurrentConfig->SyncTime = "";
230 s[*phone].s.CurrentConfig->DebugFile = malloc( strlen(logfile)+1 );
231 if (s[*phone].s.CurrentConfig->DebugFile == NULL) return GE_MOREMEMORY;
232 strcpy(s[*phone].s.CurrentConfig->DebugFile,logfile);
233 strcpy(s[*phone].s.CurrentConfig->DebugLevel,logfiletype);
234 s[*phone].s.CurrentConfig->LockDevice = "";
235 s[*phone].s.CurrentConfig->StartInfo = "yes";
236 s[*phone].s.CurrentConfig->Device = malloc( strlen(device)+1 );
237 if (s[*phone].s.CurrentConfig->Device == NULL) return GE_MOREMEMORY;
238 strcpy(s[*phone].s.CurrentConfig->Device,device);
239 strcpy(s[*phone].s.CurrentConfig->Model,model);
241 if (connection[0] == 0) {
242 CheckConnectionType(phone,connection,"at115200",&error,&error2,PhoneCallBack,SecurityCallBack,SMSCallBack);
243 switch (error) {
244 case GE_NONE:
245 case GE_DEVICEOPENERROR:
246 return error;
247 default:
248 if (error2 != GE_NONE) return error2;
250 CheckConnectionType(phone,connection,"at19200",&error,&error2,PhoneCallBack,SecurityCallBack,SMSCallBack);
251 switch (error) {
252 case GE_NONE:
253 case GE_DEVICEOPENERROR:
254 return error;
255 default:
256 if (error2 != GE_NONE) return error2;
258 CheckConnectionType(phone,connection,"fbus",&error,&error2,PhoneCallBack,SecurityCallBack,SMSCallBack);
259 switch (error) {
260 case GE_NONE:
261 case GE_DEVICEOPENERROR:
262 return error;
263 default:
264 if (error2 != GE_NONE) return error2;
266 strcpy(connection,"");
267 return GE_NOTCONNECTED;
268 } else {
269 s[*phone].s.CurrentConfig->Connection = malloc( strlen(connection)+1 );
270 if (s[*phone].s.CurrentConfig->Connection == NULL) return GE_MOREMEMORY;
271 strcpy(s[*phone].s.CurrentConfig->Connection,connection);
272 s[*phone].errors = 250;
273 CreatePhoneThread(phone,PhoneCallBack,SecurityCallBack,SMSCallBack);
274 return GE_NONE;
278 GSM_Error WINAPI myendconnection(int phone)
280 GSM_Error error=GE_NONE;
282 if (s[phone].Used) {
283 s[phone].ThreadTerminate = true;
284 if (s[phone].s.opened) {
285 WaitForSingleObject(s[phone].Mutex, INFINITE );
286 error = GSM_TerminateConnection(&s[phone].s);
287 ReleaseMutex(s[phone].Mutex);
290 return error;
293 GSM_Error WINAPI mygetnetworkinfo (int phone, GSM_NetworkInfo *NetworkInfo)
295 GSM_Error error;
297 if (!s[phone].s.opened) return GE_NOTCONNECTED;
299 WaitForSingleObject(s[phone].Mutex, INFINITE );
300 error=s[phone].s.Phone.Functions->GetNetworkInfo(&s[phone].s,NetworkInfo);
301 SetErrorCounter(phone, error);
302 ReleaseMutex(s[phone].Mutex);
303 return error;
306 GSM_Error WINAPI mygetnextsmsmessage (int phone, GSM_MultiSMSMessage *sms, bool start)
308 GSM_Error error;
309 int i;
311 if (!s[phone].s.opened) return GE_NOTCONNECTED;
313 WaitForSingleObject(s[phone].Mutex, INFINITE );
314 error=s[phone].s.Phone.Functions->GetNextSMS(&s[phone].s,sms,start);
315 SetErrorCounter(phone, error);
316 ReleaseMutex(s[phone].Mutex);
317 if (error == GE_NONE) {
318 for (i=0;i<sms->Number;i++) {
319 if (sms->SMS[i].PDU == SMS_Deliver || sms->SMS[i].PDU == SMS_Status_Report) {
320 ReverseUnicodeString(sms->SMS[i].SMSC.Number);
322 ReverseUnicodeString(sms->SMS[i].Number);
323 if (sms->SMS[i].PDU != SMS_Status_Report) {
324 ReverseUnicodeString(sms->SMS[i].Name);
326 if (sms->SMS[i].Coding == GSM_Coding_Unicode || sms->SMS[i].Coding == GSM_Coding_Default) {
327 ReverseUnicodeString(sms->SMS[i].Text);
331 return error;
334 GSM_Error WINAPI myentersecuritycode(int phone, GSM_SecurityCode *Code)
336 GSM_Error error;
338 if (!s[phone].s.opened) return GE_NOTCONNECTED;
340 WaitForSingleObject(s[phone].Mutex, INFINITE );
341 error=s[phone].s.Phone.Functions->EnterSecurityCode(&s[phone].s,*Code);
342 SetErrorCounter(phone, error);
343 ReleaseMutex(s[phone].Mutex);
344 return error;
347 GSM_Error WINAPI mydeletesmsmessage (int phone, GSM_SMSMessage *sms)
349 GSM_Error error;
351 if (!s[phone].s.opened) return GE_NOTCONNECTED;
353 WaitForSingleObject(s[phone].Mutex, INFINITE );
354 error=s[phone].s.Phone.Functions->DeleteSMS(&s[phone].s,sms);
355 SetErrorCounter(phone, error);
356 ReleaseMutex(s[phone].Mutex);
357 return error;
360 void SendSMSStatus (char *Device, int status)
362 int i;
364 for (i=0;i<10;i++) {
365 if (s[i].s.opened && s[i].Used) {
366 if (strcmp(s[i].s.CurrentConfig->Device,Device)==0) {
367 if (status == 0) {
368 s[i].SendSMSStatus = GE_NONE;
369 } else {
370 s[i].SendSMSStatus = GE_UNKNOWN;
377 GSM_Error WINAPI mysendsmsmessage (int phone, GSM_SMSMessage *sms, unsigned int timeout)
379 GSM_Error error;
380 GSM_DateTime Date;
381 unsigned int i,j;
382 GSM_SMSMessage sms2;
384 if (!s[phone].s.opened) return GE_NOTCONNECTED;
386 memcpy(&sms2,sms,sizeof(GSM_SMSMessage));
388 if (sms2.SMSC.Location == 0) ReverseUnicodeString(sms2.SMSC.Number);
389 ReverseUnicodeString(sms2.Number);
390 // ReverseUnicodeString(sms2.Name);
391 if (sms2.Coding == GSM_Coding_Unicode || sms2.Coding == GSM_Coding_Default) {
392 ReverseUnicodeString(sms2.Text);
395 WaitForSingleObject(s[phone].Mutex, INFINITE );
396 s[phone].s.User.SendSMSStatus = SendSMSStatus;
397 s[phone].SendSMSStatus = GE_TIMEOUT;
399 error=s[phone].s.Phone.Functions->SendSMS(&s[phone].s,&sms2);
400 SetErrorCounter(phone, error);
401 if (error != GE_NONE) {
402 ReleaseMutex(s[phone].Mutex);
403 s[phone].s.User.SendSMSStatus = NULL;
404 return error;
406 for (j=0;j<timeout;j++) {
407 GSM_GetCurrentDateTime(&Date);
408 i=Date.Second;
409 while (i==Date.Second) {
410 GSM_ReadDevice(&s[phone].s,false);
411 if (s[phone].SendSMSStatus != GE_TIMEOUT) break;
412 GSM_GetCurrentDateTime(&Date);
413 my_sleep(20);
415 if (s[phone].SendSMSStatus != GE_TIMEOUT) break;
417 ReleaseMutex(s[phone].Mutex);
418 SetErrorCounter(phone, s[phone].SendSMSStatus);
419 s[phone].s.User.SendSMSStatus = NULL;
420 return s[phone].SendSMSStatus;
423 GSM_Error WINAPI mygetsmsstatus (int phone, GSM_SMSMemoryStatus *status)
425 GSM_Error error;
427 if (!s[phone].s.opened) return GE_NOTCONNECTED;
429 WaitForSingleObject(s[phone].Mutex, INFINITE );
430 error=s[phone].s.Phone.Functions->GetSMSStatus(&s[phone].s,status);
431 SetErrorCounter(phone, error);
432 ReleaseMutex(s[phone].Mutex);
433 return error;
436 GSM_Error WINAPI myaddsmsmessage (int phone, GSM_SMSMessage *sms)
438 GSM_Error error;
439 GSM_SMSMessage sms2;
441 if (!s[phone].s.opened) return GE_NOTCONNECTED;
443 memcpy(&sms2,sms,sizeof(GSM_SMSMessage));
444 if (sms2.SMSC.Location == 0) ReverseUnicodeString(sms2.SMSC.Number);
445 ReverseUnicodeString(sms2.Number);
446 ReverseUnicodeString(sms2.Name);
447 if (sms2.Coding == GSM_Coding_Unicode || sms2.Coding == GSM_Coding_Default) {
448 ReverseUnicodeString(sms2.Text);
451 WaitForSingleObject(s[phone].Mutex, INFINITE );
452 error=s[phone].s.Phone.Functions->AddSMS(&s[phone].s,&sms2);
453 SetErrorCounter(phone, error);
454 ReleaseMutex(s[phone].Mutex);
455 return error;
458 void WINAPI mygetnetworkname(char *NetworkCode, char *NetworkName)
460 memcpy(NetworkName,GSM_GetNetworkName(NetworkCode),UnicodeLength(GSM_GetNetworkName(NetworkCode))*2+2);
461 ReverseUnicodeString(NetworkName);
464 void WINAPI mygetgammuversion(char *version)
466 sprintf(version, "%s",VERSION);
469 GSM_Error WINAPI mygetimei(int phone, char *IMEI)
471 GSM_Error error;
473 if (!s[phone].s.opened) return GE_NOTCONNECTED;
475 WaitForSingleObject(s[phone].Mutex, INFINITE );
476 error=s[phone].s.Phone.Functions->GetIMEI(&s[phone].s);
477 SetErrorCounter(phone, error);
478 ReleaseMutex(s[phone].Mutex);
479 if (error == GE_NONE) strcpy(IMEI,s[phone].s.Phone.Data.IMEI);
480 return error;
483 GSM_Error WINAPI mygetmanufacturer(int phone, char *manufacturer)
485 GSM_Error error;
487 if (!s[phone].s.opened) return GE_NOTCONNECTED;
489 WaitForSingleObject(s[phone].Mutex, INFINITE );
490 error=s[phone].s.Phone.Functions->GetManufacturer(&s[phone].s);
491 SetErrorCounter(phone, error);
492 ReleaseMutex(s[phone].Mutex);
493 if (error == GE_NONE) strcpy(manufacturer,s[phone].s.Phone.Data.Manufacturer);
494 return error;
497 GSM_Error WINAPI mygetmodel(int phone, char *model)
499 if (!s[phone].s.opened) return GE_NOTCONNECTED;
500 strcpy(model,s[phone].s.Phone.Data.Model);
501 return GE_NONE;
504 GSM_Error WINAPI mygetmodelname(int phone, char *model)
506 if (!s[phone].s.opened) return GE_NOTCONNECTED;
507 strcpy(model,s[phone].s.Phone.Data.ModelInfo->model);
508 return GE_NONE;
511 GSM_Error WINAPI mygetfirmwareversion(int phone, double *version)
513 if (!s[phone].s.opened) return GE_NOTCONNECTED;
514 *version = s[phone].s.Phone.Data.VerNum;
515 return GE_NONE;
518 GSM_Error WINAPI myreset(int phone, bool hard)
520 GSM_Error error;
522 if (!s[phone].s.opened) return GE_NOTCONNECTED;
524 WaitForSingleObject(s[phone].Mutex, INFINITE );
525 error=s[phone].s.Phone.Functions->Reset(&s[phone].s,hard);
526 SetErrorCounter(phone, error);
527 ReleaseMutex(s[phone].Mutex);
528 return error;
532 GSM_Error WINAPI mysmscounter(int MessageLength,
533 unsigned char *MessageBuffer,
534 GSM_UDH UDH,
535 GSM_Coding_Type Coding,
536 int *SMSNum,
537 int *CharsLeft)
539 /* FIXME. Reverse MessageBuffer */
540 GSM_SMSCounter(MessageLength,MessageBuffer,UDH,Coding,SMSNum,CharsLeft);
541 return GE_NONE;
544 GSM_Error WINAPI mymakemultipartsms(unsigned char *MessageBuffer,
545 int MessageLength,
546 GSM_UDH UDHType,
547 GSM_Coding_Type Coding,
548 int Class,
549 unsigned char ReplaceMessage,
550 GSM_MultiSMSMessage *SMS)
552 int i;
554 /* FIXME. Reverse MessageBuffer */
555 GSM_MakeMultiPartSMS(SMS,MessageBuffer,MessageLength,UDHType,Coding,Class,ReplaceMessage);
556 for (i=0;i<SMS->Number;i++) {
557 if (SMS->SMS[i].Coding == GSM_Coding_Unicode || SMS->SMS[i].Coding == GSM_Coding_Default) {
558 ReverseUnicodeString(SMS->SMS[i].Text);
561 return GE_NONE;
564 /* ------------------ see dct4.c ------------------------------------------- */
566 static GSM_Error DCT4_ReplyGetSimlock(GSM_Protocol_Message msg, GSM_StateMachine *s)
568 int i,j=0;
570 switch (msg.Buffer[3]) {
571 case 0x0D:
572 for (i=14;i<22;i++) {
573 sprintf(s->Phone.Data.PhoneString+j,"%02x",msg.Buffer[i]);
574 j=j+2;
576 return GE_NONE;
578 return GE_UNKNOWNRESPONSE;
581 char SecLength;
583 static GSM_Error DCT4_ReplyGetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s)
585 if (msg.Length > 12) {
586 SecLength = msg.Buffer[13];
587 if ((msg.Buffer[17]+18) == msg.Length) {
588 sprintf(s->Phone.Data.PhoneString,"%s",msg.Buffer+18);
591 return GE_NONE;
594 static GSM_Reply_Function UserReplyFunctions4[] = {
595 {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x05,ID_User1 },
596 {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x0D,ID_User1 },
598 {DCT4_ReplyGetSimlock, "\x53",0x03,0x0D,ID_User6 },
599 {NULL, "\x00",0x00,0x00,ID_None }
602 GSM_Error WINAPI mygetdct4simlocknetwork(int phone, char *network)
604 unsigned char GetSimlock[4] = {N6110_FRAME_HEADER, 0x0C};
605 GSM_Error error;
607 if (!s[phone].s.opened) return GE_NOTCONNECTED;
609 WaitForSingleObject(s[phone].Mutex, INFINITE );
610 s[phone].s.User.UserReplyFunctions = UserReplyFunctions4;
611 network[0] = 0;
612 s[phone].s.Phone.Data.PhoneString = network;
613 error=GSM_WaitFor (&s[phone].s, GetSimlock, 4, 0x53, 4, ID_User6);
614 SetErrorCounter(phone, error);
615 ReleaseMutex(s[phone].Mutex);
616 return error;
619 GSM_Error WINAPI mygetdct4securitycode(int phone, char *code)
621 GSM_Error error;
622 unsigned char getlen[]={0x00, 0x08, 0x01, 0x0C,
623 0x00, 0x23, //ID
624 0x00, 0x00, //Index
625 0x00, 0x00};
626 unsigned char read[]={0x00, 0x08, 0x02, 0x04,
627 0x00, 0x23, //ID
628 0x00, 0x00, //Index
629 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00,
631 0x00}; //Length
633 if (!s[phone].s.opened) return GE_NOTCONNECTED;
635 WaitForSingleObject(s[phone].Mutex, INFINITE );
636 s[phone].s.User.UserReplyFunctions = UserReplyFunctions4;
637 code[0] = 0;
638 s[phone].s.Phone.Data.PhoneString = code;
640 SecLength = 0;
641 error=GSM_WaitFor (&s[phone].s, getlen, sizeof(getlen), 0x23, 1, ID_User1);
642 SetErrorCounter(phone, error);
643 if (SecLength != 0) {
644 read[17] = SecLength;
645 error=GSM_WaitFor (&s[phone].s, read, sizeof(read), 0x23, 5, ID_User1);
646 SetErrorCounter(phone, error);
648 ReleaseMutex(s[phone].Mutex);
649 return error;
652 /* ------------------------------------------------------------------------- */
654 int WINAPI mygetstructuresize(int i)
656 switch (i) {
657 case 0: return sizeof(GSM_SMSMessage);
658 case 1: return sizeof(GSM_SMSC);
659 case 2: return sizeof(GSM_SMS_State);
660 case 3: return sizeof(GSM_UDHHeader);
661 case 4: return sizeof(bool);
662 case 5: return sizeof(GSM_DateTime);
663 case 6: return sizeof(int);
664 case 7: return sizeof(GSM_NetworkInfo);
665 case 8: return sizeof(GSM_UDH);
667 return 0;
670 BOOL WINAPI DllMain ( HANDLE hModule,
671 DWORD ul_reason_for_call,
672 LPVOID lpReserved )
674 int i;
676 switch (ul_reason_for_call) {
677 case DLL_PROCESS_ATTACH:
678 for (i=0;i<10;i++) {
679 s[i].s.opened = false;
680 s[i].Used = false;
681 s[i].dwThreadID = 0;
683 break;
684 case DLL_THREAD_ATTACH:
685 case DLL_THREAD_DETACH:
686 break;
687 case DLL_PROCESS_DETACH:
688 for (i=0;i<10;i++) {
689 myendconnection(i);
691 break;
693 return TRUE;