📄 nk2110.c
字号:
X(ALPHA, 22) X(PREV, 23) X(NEXT, 24) X(SOFTA, 25) X(SOFTB, 26)#if 0 X(STO, 19) /* These are not present on 2110, so I can't test this. Enable once tested. */ X(RCL, 20) X(MUTE, 28)#endif default: fprintf(stderr, "Unknown key %d\n", c); }#undef X}static voidPressString(char *s, int upcase){ static int lastchar; static int lastupcase = 1; if (lastchar == *s) { fprintf(stderr, "***collision"); PressKey(ALPHA, 0); PressKey(ALPHA, 0); lastupcase = 1; } while (*s) { lastchar = *s; PressKey(*s, 0); if (upcase != lastupcase) { fprintf(stderr, "***size change"); msleep_poll(1500); PressKey(*s, 1); lastupcase = upcase; } s++; }}/* * This is able to press keys at 62letters/36seconds, tested on message * "Tohle je testovaci zprava schvalne za jak dlouho ji to napise" * Well, it is possible to write that message in 17seconds... */static voidHandleKey(char c){ switch(c) {#define X(a, b) case a: PressString(b, 0); break; X('-', "1"); X('?', "11"); X('!', "111"); X(',', "1111"); X('.', "11111"); X(':', "111111"); X('"', "1111111"); X('\'', "11111111"); X('&', "111111111"); X('$', "1111111111");/* X('$', "11111111111"); libra, not in ascii */ X('(', "111111111111"); X(')', "1111111111111"); X('/', "11111111111111"); X('%', "111111111111111"); X('@', "1111111111111111"); X('_', "11111111111111111"); X('=', "111111111111111111"); X('a', "2"); X('b', "22"); X('c', "222"); X('d', "3"); X('e', "33"); X('f', "333"); X('g', "4"); X('h', "44"); X('i', "444"); X('j', "5"); X('k', "55"); X('l', "555"); X('m', "6"); X('n', "66"); X('o', "666"); X('p', "7"); X('q', "77"); X('r', "777"); X('s', "7777"); X('t', "8"); X('u', "88"); X('v', "888"); X('w', "9"); X('x', "99"); X('y', "999"); X('z', "9999");#undef X#define X(a, b) case a: PressString(b, 1); break; X('A', "2"); X('B', "22"); X('C', "222"); X('D', "3"); X('E', "33"); X('F', "333"); X('G', "4"); X('H', "44"); X('I', "444"); X('J', "5"); X('K', "55"); X('L', "555"); X('M', "6"); X('N', "66"); X('O', "666"); X('P', "7"); X('Q', "77"); X('R', "777"); X('S', "7777"); X('T', "8"); X('U', "88"); X('V', "888"); X('W', "9"); X('X', "99"); X('Y', "999"); X('Z', "9999");#undef X case ' ': PressKey('#', 0); break; case '+': PressKey(ALPHA, 0); PressKey('*', 0); PressKey('*', 0); PressKey(ALPHA, 0); break; case '*': case '#': case '0' ... '9': PressKey(ALPHA, 0); PressKey(c, 0); PressKey(ALPHA, 0); break; default: PressKey(c, 0); }}static gn_errorHandleString(char *s){ while (*s) { HandleKey(*s); s++; } fprintf(stderr,"***end of input"); PressKey(lastkey, 1); return GN_ERR_NONE;}static voidRegister(void){ u8 reg[] = { 1, 1, 0x0f, 1, 0x0f }; SendFrame( reg, 0xe9, 5 );}static gn_errorEnableDisplayOutput(GSM_Statemachine *sm){ /* LN_UC_SHARE, LN_UC_SHARE, LN_UC_RELEASE, LN_UC_RELEASE, LN_UC_KEEP */ u8 pkt[] = {3, 3, 0, 0, 1}; msleep_poll(500); fprintf(stderr, "\nShould display output\n"); if (!OutputFn) { pkt[0] = 0; pkt[1] = 0; } PacketOK = false; SendCommand(pkt, 0x19, 5); fprintf(stderr, "\nGrabbing display"); waitfor(PacketOK, 0); if ((PacketData[3] != 0xcd) || (PacketData[2] != 1) || (PacketData[4] != 1 /* LN_UC_REQUEST_OK */)) fprintf(stderr, "Something is very wrong with GrabDisplay\n"); fprintf(stderr, "Display grabbed okay (waiting)\n"); msleep_poll(500); fprintf(stderr, "Okay\n"); return GN_ERR_NONE;}static gn_error SMS_Reserve(GSM_Statemachine *sm){ u8 pkt[] = { 0x10, LM_SMS_RESERVE_PP, LN_SMS_NORMAL_RESERVE }; PacketOK = false; msleep_poll(3000); SendCommand(pkt, LM_SMS_COMMAND, sizeof(pkt)); PacketOK = 0; waitfor(PacketOK, 100); if (!PacketOK) eprintf("No reply trying to reserve SMS-es\n"); if (PacketData[3] != LM_SMS_EVENT) eprintf("Bad reply trying to reserve SMS-es\n"); if (SMSData[0] != LM_SMS_PP_RESERVE_COMPLETE) eprintf("Not okay trying to reserve SMS-es (%d)\n", SMSData[0]); SMSpos = 0; return GN_ERR_NONE;}static gn_error SMS_UnReserve(GSM_Statemachine *sm){ u8 pkt[] = {0x10, LM_SMS_UNRESERVE_PP }; PacketOK = false; msleep_poll(3000); SendCommand(pkt, LM_SMS_COMMAND, sizeof(pkt)); SMSpos = 0; return GN_ERR_NONE;}/* This is the main loop for the MB21 functions. When N2110_Initialise is called a thread is created to run this loop. This loop is exited when the application calls the N2110_Terminate function. */static voidRegisterMe(void){ fprintf(stderr, "Initializing... "); /* Do initialisation stuff */ LastChar = GetTime(); if (OpenSerial() != true) { N2110_LinkOK = false; return; } msleep(100); while(!N2110_LinkOK) { fprintf(stderr, "registration... "); Register(); msleep_poll(100); } fprintf(stderr, "okay\n");}/* Initialise variables and state machine. */static gn_errorInitialise(GSM_Statemachine *state){ GSM_Data data; /* Copy in the phone info */ memcpy(&(state->Phone), &phone_nokia_2110, sizeof(GSM_Phone)); layout.Type = 8; layout.SendHeader = 6; layout.ReadHeader = 4; layout.Deliver = nk2110_deliver; RequestTerminate = false; N2110_LinkOK = false; setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); memset(VersionInfo, 0, sizeof(VersionInfo)); strcpy(PortDevice, state->Link.PortDevice); switch (state->Link.ConnectionType) { case GCT_Serial: RegisterMe(); break; default: return GN_ERR_NOTSUPPORTED; break; } SM_Initialise(state); GSM_DataClear(&data); return GN_ERR_NONE;}/* Routine to get specifed phone book location. Designed to be called by application. Will block until location is retrieved or a timeout/error occurs. */static gn_errorGetPhonebookLocation(GSM_PhonebookEntry *entry){ u8 pkt[] = {0x1a, 0 /* 1 == phone */, 0}; int i; pkt[1] = 3 + (entry->MemoryType != GMT_ME); pkt[2] = entry->Location; PacketOK = false; SendCommand(pkt, LN_LOC_COMMAND, 3); waitfor(PacketOK, 0); if ((PacketData[3] != 0xc9) || (PacketData[4] != 0x1a)) { fprintf(stderr, "Something is very wrong with GetPhonebookLocation\n"); return GN_ERR_BUSY; } ddprintf("type= %x\n", PacketData[5]); ddprintf("location= %x\n", PacketData[6]); ddprintf("status= %x\n", PacketData[7]); for (i=8; PacketData[i]; i++) { ddprintf("%c", PacketData[i]); } strcpy(entry->Name, (void *)&PacketData[8]); i++; strcpy(entry->Number, (void *)&PacketData[i]); for (; PacketData[i]; i++) { ddprintf("%c", PacketData[i]); } ddprintf("\n"); entry->Empty = false; entry->Group = 0; return GN_ERR_NONE);}/* Routine to write phonebook location in phone. Designed to be called by application code. Will block until location is written or timeout occurs. */static gn_errorWritePhonebookLocation(GSM_PhonebookEntry *entry){ u8 pkt[999] = {0x1b, 0 /* 1 == phone */, 0}; pkt[1] = 3 + (entry->MemoryType != GMT_ME); pkt[2] = entry->Location; strcpy(&pkt[3], entry->Name); strcpy(&pkt[3+strlen(entry->Name)+1], entry->Number); PacketOK = false; SendCommand(pkt, LN_LOC_COMMAND, 3+strlen(entry->Number)+strlen(entry->Name)+2); waitfor(PacketOK, 0); printf("okay?\n"); if ((PacketData[3] != 0xc9) || (PacketData[4] != 0x1b)) { fprintf(stderr, "Something is very wrong with WritePhonebookLocation\n"); return GN_ERR_BUSY; } printf("type= %x\n", PacketData[5]); printf("location= %x\n", PacketData[6]); printf("status= %x\n", PacketData[7]); return GN_ERR_NONE);}static gn_errorGetSMSStatus(GSM_SMSMemoryStatus *Status){ Status->Unread = 0; Status->Number = 5; return GN_ERR_NONE;}#endif /* WIN32 */static gn_error link_Loop(struct timeval *tm){ POLLIT; return GN_ERR_NONE;}gn_error P2110_Functions(GSM_Operation op, GSM_Data *data, GSM_Statemachine *state){ gn_error err = GN_ERR_NONE;// printf("Asked for %d\n", op); switch (op) { case GOP_Init: state->Link.Loop = link_Loop; err = Initialise(state); break; case GOP_Terminate: /* Request termination of thread */ RequestTerminate = true; return PGEN_Terminate(data, state); case GOP_Identify: case GOP_GetModel: case GOP_GetRevision: if (!Model) err = GetVersionInfo(); if (err) break; if (data->Model) strncpy(data->Model, Model, 64); if (data->Revision) strncpy(data->Revision, Revision, 64); break; case GOP_GetBatteryLevel: err = GetBatteryLevel(data->BatteryUnits, data->BatteryLevel); break; case GOP_GetRFLevel: err = GetRFLevel(data->RFUnits, data->RFLevel); break;#if 0 case GOP_GetMemoryStatus: err = N2110_GetMemoryStatus(data, state); break;#endif case GOP_DisplayOutput: OutputFn = data->DisplayOutput->OutputFn; err = EnableDisplayOutput(state); break; case GOP_GetSMS: msleep(100); err = GetSMSMessage(data); break; case GOP_DeleteSMS: err = SMS(data->SMSMessage, 3); break; case GOP_ReadPhonebook: err = GetPhonebookLocation(data->PhonebookEntry); break; case GOP_WritePhonebook: err = WritePhonebookLocation(data->PhonebookEntry); break; case GOP_OnSMS: OnSMSFn = data->OnSMS; if (OnSMSFn) { CheckIncomingSMS(1); CheckIncomingSMS(2); CheckIncomingSMS(3); CheckIncomingSMS(4); CheckIncomingSMS(5); err = SMS_Reserve(state); } else err = SMS_UnReserve(state); break; case GOP_PollSMS: /* Our phone is able to notify us... but we do not want to burn 100% CPU polling */ { struct timeval tm; static long long lastpoll = 0; tm.tv_sec = 0; tm.tv_usec = 50000; device_select(&tm); if (lastpoll + 10000000 < GetTime()) { fprintf(stderr, "Trying to capture leftover messages\n"); CheckIncomingSMS(1); CheckIncomingSMS(2); CheckIncomingSMS(3); CheckIncomingSMS(4); CheckIncomingSMS(5); } sleep(4); } break; case GOP_PollDisplay: break; default: err = GN_ERR_NOTIMPLEMENTED; } return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -