X-Git-Url: https://git.jankratochvil.net/?p=gnokii.git;a=blobdiff_plain;f=mgnetd%2Fmgnetd.c;fp=mgnetd%2Fmgnetd.c;h=b4bc8967e32d6c5897e6b34d8de76ebadccc9f78;hp=0000000000000000000000000000000000000000;hb=2e0972b02d101bb0d8e9d3e15d2ac80def491a63;hpb=cc37b87508c91b5d4f21fd4bbc298104ae7de1dc;ds=sidebyside diff --git a/mgnetd/mgnetd.c b/mgnetd/mgnetd.c new file mode 100644 index 0000000..b4bc896 --- /dev/null +++ b/mgnetd/mgnetd.c @@ -0,0 +1,556 @@ +/* + + G N O K I I + + A Linux/Unix toolset and driver for Nokia mobile phones. + + Released under the terms of the GNU GPL, see file COPYING for more details. + + Mainline code for mgnetd daemon. + + Last modification: 07.02.2002 + Ralf Thelen + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__svr4__) || defined(__FreeBSD__) + # include /* for bzero */ +#endif + +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "files/cfgreader.h" +#include "gsm-common.h" +#include "gsm-api.h" +#include "mgnetd.h" + +#ifdef USE_NLS + #include +#endif + +/* Global variables */ +char *Model; /* Model from .gnokiirc file. */ +char *Port; /* Port from .gnokiirc file */ +char *Initlength; /* Init length from .gnokiirc file */ +char *Connection; /* Connection type from .gnokiirc file */ +char *SynchronizeTime; +char *BinDir; /* Directory of the mgnokiidev command */ + + +void usage(void) +{ + + fprintf(stdout, _("mgnetd Version %d.%d, a udp server for mygnokii\n based on Version %s\n" + "Built %s %s for %s on %s \n") + ,MG_NET_API_MAJOR_VERSION,MG_NET_API_MINOR_VERSION, VERSION, __TIME__, __DATE__, Model, Port); + fprintf(stdout, _(" usage: mgnetd passwd\n")); + exit(1); +} + +/* fbusinit is the generic function which waits for the FBUS link. The limit + is 10 seconds. After 10 seconds we quit. */ + +void fbusinit(void (*rlp_handler)(RLP_F96Frame *frame)) +{ + + int count=0; + GSM_Error error; + +#ifndef WIN32 + if (strcmp(GetMygnokiiVersion(),VERSION)!=0) + fprintf(stderr,_("WARNING: version of installed libmygnokii.so (%s) is different to version of mgnetd (%s)\n"),GetMygnokiiVersion(),VERSION); +#endif + + /* Initialise the code for the GSM interface. */ + error = GSM_Initialise(Model, Port, Initlength, GetConnectionTypeFromString(Connection), rlp_handler, SynchronizeTime); + + if (error != GE_NONE) { + fprintf(stderr, _("GSM/FBUS init failed! (Unknown model ?). Quitting.\n")); + exit(-1); + } + + /* First (and important!) wait for GSM link to be active. We allow 10 + seconds... */ + while (count++ < 200 && *GSM_LinkOK == false) + usleep(50000); + + if (*GSM_LinkOK == false) { + fprintf (stderr, _("Hmmm... GSM_LinkOK never went true. Quitting.\n")); + exit(-1); + } +} + + +/* + main + simple udp-based server + */ +int main(int argc, char *argv[]) +{ + +MG_api_request rq; +MG_rq_version version; +MG_rq_identify ident; +MG_rq_memorystatus status; +MG_rq_phonebook_location ph; +MG_rq_send_sms sms; + +GSM_PhonebookEntry entry; +GSM_MemoryStatus stats; +GSM_RFUnits rf_units = GRF_Arbitrary; +GSM_BatteryUnits batt_units = GBU_Arbitrary; + +GSM_MultiSMSMessage MultiSMS; +GSM_SMSMessageType SMSType=GST_SMS; +int SMSClass = -1; +bool SMSReply = false; +GSM_Coding_Type SMSCoding = GSM_Coding_Default; +GSM_UDH SMSUDHType = GSM_NoUDH; + +char password[8]; + +char memory_type_string[20]; + +float rflevel=-1, batterylevel=-1; + +time_t curr_t, last_t; + +int s; /* socket descriptor */ +int cc; /* contains the number of bytes read */ + +struct servent *sp; /* pointer to service information */ + +struct sockaddr_in myaddr; /* for local socket address */ +struct sockaddr_in clientaddr; /* for client's socket address */ + +extern int errno; /* for unblocking io */ + +int addrlen; +int error_cnt = 0; +int i; + +/* For GNU gettext */ +#ifdef USE_NLS + textdomain("gnokii"); + setlocale(LC_ALL, "pl_PL"); //here is string for Polish localisation +#endif + + /* Read config file */ + if (CFG_ReadConfig(&Model, &Port, &Initlength, &Connection, &BinDir, &SynchronizeTime,false) < 0) { + exit(-1); + } + +/* Handle command line arguments. */ +if (argc != 2) usage(); + +/* get password from commandline */ +strncpy(password,argv[1],8); + + +/* init timevars */ +curr_t = last_t = time(NULL); + +/* clear out address structures */ +memset ((char *)&myaddr, 0, sizeof(struct sockaddr_in)); +memset ((char *)&clientaddr, 0, sizeof(struct sockaddr_in)); + +/* Set up address structure for the socket. */ +myaddr.sin_family = AF_INET; +myaddr.sin_addr.s_addr = INADDR_ANY; + +sp = getservbyname ("mygnokii", "udp"); + if (sp == NULL) { +#ifdef DEBUG + printf("mygnokii not found in /etc/services\n"); + printf("using default port 50963\n"); +#endif + myaddr.sin_port = htons(50963); + } + else myaddr.sin_port = sp->s_port; + + + /* Create the socket. */ + s = socket (AF_INET, SOCK_DGRAM, 0); + if (s == -1) { + perror(argv[0]); + printf("%s: unable to create socket\n", argv[0]); + exit(1); + } + + /* Bind the server's address to the socket. */ + if (bind(s, (struct sockaddr *) &myaddr, sizeof(struct sockaddr)) == -1) { + perror(argv[0]); + printf("%s: unable to bind address\n", argv[0]); + exit(1); + } + + /* Make socket unblocking */ + if ( fcntl(s, F_SETFL, O_NONBLOCK) == -1) { + perror(argv[0]); + printf("%s: unable to make socket unblocking\n", argv[0]); + exit(1); + } + + + setpgrp(); + + switch (fork()) { + case -1: /* Unable to fork, for some reason. */ + perror(argv[0]); + printf("%s: unable to fork daemon\n", argv[0]); + exit(1); + + case 0: + + /* init GSM Interface */ + fbusinit(NULL); + printf("init done, daemonizing\n"); + +#ifndef DEBUG + close(0); + close(1); + close(2); +#endif + + for(;;) { + addrlen = sizeof(struct sockaddr_in); + + cc = recvfrom(s, &rq, sizeof(rq), 0, + (struct sockaddr *) &clientaddr, &addrlen); + + if ( cc == -1) + { + if ( errno != EAGAIN) exit(1); + else + { /* no data -> do some usefull things */ + /* required for infrared connections to prevent timeouts */ + curr_t = time(NULL); + if ( difftime(curr_t, last_t) > 5 ) + { + if (GSM->GetRFLevel(&rf_units, &rflevel) != GE_NONE) + error_cnt++; + else + error_cnt=0; + if (GSM->GetBatteryLevel(&batt_units, &batterylevel) != GE_NONE) + error_cnt++; + else + error_cnt=0; + last_t = curr_t = time(NULL); + } + continue; + } + }/* if( cc == -1) */ + + /* don't answer if we see wrong password */ + if (strncmp(password, rq.passwd, 8) != 0) continue; + +#ifdef DEBUG + printf("server: received cmd Nr. %d\n",rq.cmd); +#endif + switch (rq.cmd) + { + case MG_INIT: + /* RTH FIXME: for Version 0.1, init is done at startup */ + break; + case MG_EXIT: + GSM->Terminate(); + break; + case MG_VERSION: + version.major = MG_NET_API_MAJOR_VERSION; + version.minor = MG_NET_API_MINOR_VERSION; + memcpy(rq.buffer, &version, sizeof(version)); + break; + case MG_IDENTIFY: + /* RTH FIXME: check errors */ + while (GSM->GetIMEI(ident.imei) != GE_NONE) sleep(1); + while (GSM->GetRevision(ident.rev) != GE_NONE) sleep(1); + while (GSM->GetModel(ident.model) != GE_NONE) sleep(1); + memcpy(rq.buffer, &ident, sizeof(ident)); + break; + + case MG_MEMORYSTATUS: + memcpy(&status, rq.buffer, sizeof(status)); +#ifdef DEBUG + printf("server: getmemorystaus for %s requested\n",status.memtype); +#endif + if (!GetMemoryTypeID(status.memtype, &stats.MemoryType)) + { + rq.cmd = -1; /* error */ + break; + } + if ( GSM->GetMemoryStatus( &stats) != GE_NONE) + { + rq.cmd = -1; /* error */ + break; + } + status.free = stats.Free; + status.used = stats.Used; + memcpy(rq.buffer, &status, sizeof(status)); + break; + case MG_GET_MEMORY_LOCATION: + memcpy(&ph, rq.buffer, sizeof(ph)); +#ifdef DEBUG + printf("server: getmemorylocation for %s, Location: %d requested\n",ph.memtype,ph.location); +#endif + ph.name[0] = ph.group[0] = ph.nr_general[0] = ph.nr_mobile[0] = ph.nr_work[0] = '\0'; + ph.nr_fax[0] = ph.nr_home[0] = ph.note[0] = ph.postal[0] = ph.email[0] = '\0'; + if (!GetMemoryTypeID(ph.memtype, &entry.MemoryType)) + { + rq.cmd = -1; /* error */ + break; + } + entry.Location = ph.location; + GetMemoryTypeString(memory_type_string, &entry.MemoryType); + if ( GSM->GetMemoryLocation(&entry) != GE_NONE) + { + rq.cmd = -1; /* error */ + break; + } + strcpy(ph.name,entry.Name); + strcpy(ph.nr_general,entry.Number); + //strcpy(ph.group,NAMEOF:entry.group); + for( i = 0; i < entry.SubEntriesCount; i++ ) + { + switch(entry.SubEntries[i].EntryType) + { + case GSM_Number: + switch(entry.SubEntries[i].NumberType) + { + case GSM_Mobile: + strcpy(ph.nr_mobile,entry.SubEntries[i].data.Number); + break; + case GSM_Work: + strcpy(ph.nr_work,entry.SubEntries[i].data.Number); + break; + case GSM_Fax: + strcpy(ph.nr_fax,entry.SubEntries[i].data.Number); + break; + case GSM_Home: + strcpy(ph.nr_home,entry.SubEntries[i].data.Number); + break; + default: + break; + } + break; + case GSM_Note: + strcpy(ph.note,entry.SubEntries[i].data.Number); + break; + case GSM_Postal: + strcpy(ph.postal,entry.SubEntries[i].data.Number); + break; + case GSM_Email: + strcpy(ph.email,entry.SubEntries[i].data.Number); + break; + default: + break; + } + }//for + memcpy(rq.buffer, &ph, sizeof(ph)); + break; + case MG_WRITE_PHONEBOOK_LOCATION: + memcpy(&ph, rq.buffer, sizeof(ph)); +#ifdef DEBUG + printf("server: writememorylocation for Location: %d requested\n",ph.location); +#endif + if (!GetMemoryTypeID(ph.memtype, &entry.MemoryType)) + { + rq.cmd = -1; /* error */ + break; + } + GetMemoryTypeString(memory_type_string, &entry.MemoryType); + if ( GSM->GetMemoryLocation(&entry) != GE_NONE) + { + rq.cmd = -1; /* error */ + break; + } + entry.Location = ph.location; + entry.SubEntriesCount = 0; + strcpy(entry.Name,ph.name); + strcpy(entry.Number,ph.nr_general); + //if ( ph.group[0] != '\0') Version 0.3 !! + if ( ph.nr_mobile[0]!= '\0') + { + entry.SubEntries[entry.SubEntriesCount].EntryType = GSM_Number; + entry.SubEntries[entry.SubEntriesCount].NumberType = GSM_Mobile; + strcpy(entry.SubEntries[entry.SubEntriesCount].data.Number,ph.nr_mobile); + entry.SubEntriesCount++; + } + if ( ph.nr_work[0]!= '\0') + { + entry.SubEntries[entry.SubEntriesCount].EntryType = GSM_Number; + entry.SubEntries[entry.SubEntriesCount].NumberType = GSM_Work; + strcpy(entry.SubEntries[entry.SubEntriesCount].data.Number,ph.nr_work); + entry.SubEntriesCount++; + } + if ( ph.nr_fax[0]!= '\0') + { + entry.SubEntries[entry.SubEntriesCount].EntryType = GSM_Number; + entry.SubEntries[entry.SubEntriesCount].NumberType = GSM_Fax; + strcpy(entry.SubEntries[entry.SubEntriesCount].data.Number,ph.nr_fax); + entry.SubEntriesCount++; + } + if ( ph.nr_home[0]!= '\0') + { + entry.SubEntries[entry.SubEntriesCount].EntryType = GSM_Number; + entry.SubEntries[entry.SubEntriesCount].NumberType = GSM_Home; + strcpy(entry.SubEntries[entry.SubEntriesCount].data.Number,ph.nr_home); + entry.SubEntriesCount++; + } + if ( ph.note[0]!= '\0') + { + entry.SubEntries[entry.SubEntriesCount].EntryType = GSM_Note; + strcpy(entry.SubEntries[entry.SubEntriesCount].data.Number,ph.note); + entry.SubEntriesCount++; + } + if ( ph.postal[0]!= '\0') + { + entry.SubEntries[entry.SubEntriesCount].EntryType = GSM_Postal; + strcpy(entry.SubEntries[entry.SubEntriesCount].data.Number,ph.postal); + entry.SubEntriesCount++; + } + if ( ph.email[0]!= '\0') + { + entry.SubEntries[entry.SubEntriesCount].EntryType = GSM_Email; + strcpy(entry.SubEntries[entry.SubEntriesCount].data.Number,ph.email); + entry.SubEntriesCount++; + } + + /* This is to send other exports (like from 6110) to 7110 */ + if (!entry.SubEntriesCount) { + entry.SubEntriesCount = 1; + entry.SubEntries[0].EntryType = GSM_Number; + entry.SubEntries[0].NumberType = GSM_General; + entry.SubEntries[0].BlockNumber = 2; + strcpy(entry.SubEntries[0].data.Number, entry.Number); + } + + if (GSM->WritePhonebookLocation(&entry) != GE_NONE) + { + rq.cmd = -1; /* error */ + break; + } + memcpy(rq.buffer, &ph, sizeof(ph)); + break; + case MG_DELETE_PHONEBOOK_LOCATION: + memcpy(&ph, rq.buffer, sizeof(ph)); +#ifdef DEBUG + printf("server: deletememorylocation for Location: %d requested\n",ph.location); +#endif + if (!GetMemoryTypeID(ph.memtype, &entry.MemoryType)) + { + rq.cmd = -1; /* error */ + break; + } + GetMemoryTypeString(memory_type_string, &entry.MemoryType); + if ( GSM->GetMemoryLocation(&entry) != GE_NONE) + { + rq.cmd = -1; /* error */ + break; + } + entry.SubEntriesCount = 0; + entry.Name[0] = '\0'; + entry.Number[0] = '\0'; + entry.Location = ph.location; + if (GSM->WritePhonebookLocation(&entry) != GE_NONE) + { + rq.cmd = -1; /* error */ + break; + } + memcpy(rq.buffer, &ph, sizeof(ph)); + break; + case MG_SEND_SMS: + memcpy(&sms, rq.buffer, sizeof(sms)); +#ifdef DEBUG + printf("server: sendsms to %s requested\n",sms.destination); + printf("server: message:%s\n",sms.message); + printf("server: Centerindex = %d\n",sms.SMSCenterIndex); +#endif + /* options */ + if(sms.enablevoice) SMSUDHType=GSM_EnableVoice; + if(sms.disablevoice) SMSUDHType=GSM_DisableVoice; + if(sms.enableemail) SMSUDHType=GSM_EnableEmail; + if(sms.disableemail) SMSUDHType=GSM_DisableEmail; + if(sms.enablefax) SMSUDHType=GSM_EnableFax; + if(sms.disablefax) SMSUDHType=GSM_DisableFax; + if(sms.unicode) SMSCoding=GSM_Coding_Unicode; + + /* message */ + GSM_MakeMultiPartSMS2(&MultiSMS,sms.message,strlen(sms.message),SMSUDHType,SMSCoding); + MultiSMS.SMS[0].Class=SMSClass; + MultiSMS.SMS[0].ReplyViaSameSMSC=SMSReply; + MultiSMS.SMS[0].Type=SMSType; + + + /* Message Center index */ + if (sms.SMSCenterIndex == 0 ) + MultiSMS.SMS[0].MessageCenter.No = 1; + else + { + if (sms.SMSCenterIndex < 0 || sms.SMSCenterIndex > 5) + { + rq.cmd = -2; /* error */ + break; + } + MultiSMS.SMS[0].MessageCenter.No = sms.SMSCenterIndex; + } + + /* Message Center number */ + if(strlen(sms.SMSCNumber) > 0) + { + MultiSMS.SMS[0].MessageCenter.No = 0; + strcpy(MultiSMS.SMS[0].MessageCenter.Number,sms.SMSCNumber); + } + + /* destination */ + strcpy(MultiSMS.SMS[0].Destination,sms.destination); + + /* delivery report */ + if(sms.delivery) MultiSMS.SMS[0].Type=GST_DR; + + /* validity */ + if (sms.SMSValidity != 0) + MultiSMS.SMS[0].Validity=sms.SMSValidity; + else + MultiSMS.SMS[0].Validity=4320; /* 3 days */ + + if( GSM->SendSMSMessage(&MultiSMS.SMS[0]) != GE_SMSSENDOK ) + { + rq.cmd = -3; /* error */ + break; + } + + memcpy(rq.buffer, &sms, sizeof(sms)); + break; + default: + rq.cmd = -1; + break; + + } + + sendto (s, &rq, sizeof(rq), 0, (struct sockaddr *) &clientaddr, addrlen); + if (rq.cmd == MG_EXIT) exit(0); + } + + default: /* Parent process comes here. */ + exit(0); + } +}