📄 smsc_at.c
字号:
(strcmp(smsc->at_modemtype, NOKIAPHONE ) == 0) || (strcmp(smsc->at_modemtype, ERICSSON ) == 0)) strcpy(sc, "00"); if(msg_type(msg)==sms) { pdu_encode(msg, &pdu[0], smsc); sprintf(command, "AT+CMGS=%d", strlen(pdu)/2); if(send_modem_command(smsc->at_fd, command, 1) == 0) { sprintf(command, "%s%s%c", sc, pdu, 26); ret = send_modem_command(smsc->at_fd, command, 0); debug("AT", 0, "send command status: %d", ret); while (ret != 0 && retries > 0) { sprintf(command, "AT+CMGS=%d", strlen(pdu)/2); if(! send_modem_command(smsc->at_fd, command, 1) == 0) break; sprintf(command, "%s%s%c", sc, pdu, 26); ret = send_modem_command(smsc->at_fd, command, 0); debug("AT", 0, "send command status: %d", ret); retries--; } if (retries<0){ debug("AT", 0, "AT: Retries exceeded \nSMS send failure :"); debug("AT", 0, "Phone number: %s", octstr_get_cstr(msg->sms.receiver)); debug("AT", 0, "SMS data: %s", octstr_get_cstr(msg->sms.msgdata)); } } } return ret;}/****************************************************************************** * There are messages to read! */int at_receive_msg(SMSCenter *smsc, Msg **msg) { *msg = list_consume(smsc->at_received); if(*msg == NULL) goto error; return 1; error: return -1;}/****************************************************************************** * Reads from the modem */static int at_data_read(int fd, Octstr *ostr) { int ret; fd_set read_fd; struct timeval tv; size_t readall; char cbuffer[257]; tv.tv_sec = 0; tv.tv_usec = 1000; readall = 0; for (;;) { memset(&cbuffer, 0, sizeof(cbuffer)); FD_ZERO(&read_fd); FD_SET(fd, &read_fd); ret = select(fd + 1, &read_fd, NULL, NULL, &tv); if (ret == -1) { if(errno==EINTR) goto got_data; if(errno==EAGAIN) goto got_data; error(errno, "Error doing select for fd"); goto error; } else if (ret == 0) goto got_data; ret = read(fd, cbuffer, 256); if (ret == -1) { goto error; } if (ret == 0) goto eof; octstr_append_data(ostr, cbuffer, strlen(cbuffer)); if(ret > 0) break; } eof: ret = 1; goto unblock; got_data: ret = 0; goto unblock; error: error(errno," read device file"); ret = -1; goto unblock; unblock: return ret; }/****************************************************************************** * Send an AT command to the modem * returns 0 if OK, -1 on failure, -2 on SIM PIN needed. * Set multiline to 1 if the command will expect more data to be sent. */static int send_modem_command(int fd, char *cmd, int multiline) { Octstr *ostr; int ret, i; ostr = octstr_create(""); /* debug */ debug("bb.smsc.at", 0, "AT: Command: %s", cmd); /* DEBUG !!! - pretend to send but just return success (0)*/ /* return 0; */ /* send the command */ write(fd, cmd, strlen(cmd)); write(fd, "\r", 1); /* We don't want to wait forever - * This is not perfect but OK for now */ for( i=0; i<1000; i++) { ret = at_data_read(fd, ostr); /* debug */ /* if(octstr_len(ostr)) { printf("Read from modem: "); for(i=0; i<octstr_len(ostr); i++) { if(octstr_get_char(ostr, i) <32) printf("[%02x] ", octstr_get_char(ostr, i)); else printf("%c ", octstr_get_char(ostr, i)); } printf("\n"); }*/ if(ret == -1) goto error; ret = octstr_search(ostr, octstr_imm("SIM PIN"), 0); if(ret != -1) { ret = -2; goto error; } if(multiline) ret = octstr_search(ostr, octstr_imm(">"), 0); else { ret = octstr_search(ostr, octstr_imm("OK"), 0); if(ret == -1) ret = octstr_search(ostr, octstr_imm("READY"), 0); if(ret == -1) ret = octstr_search(ostr, octstr_imm("CMGS"), 0); } if(ret != -1) { ret = 0; goto error; } ret = octstr_search(ostr, octstr_imm("ERROR"), 0); if(ret != -1) { ret = -1; goto error; } } ret = -1; goto error; error: for (i=0; i< octstr_len(ostr); i++) { if (octstr_get_char(ostr, i) < 32) octstr_set_char(ostr, i, ' '); } octstr_strip_blanks(ostr); debug("AT", 0, "Read from modem: '%s'",octstr_get_cstr(ostr) ); octstr_destroy(ostr); return ret;}/****************************************************************************** * Extract the first PDU in the string */static int pdu_extract(SMSCenter *smsc, Octstr **pdu) { Octstr *buffer; long len = 0; int pos = 0; int tmp; buffer = smsc->at_inbuffer; /* find the beginning of a message from the modem*/ pos = octstr_search(buffer, octstr_imm("+CMT:"), 0); if(pos == -1) goto nomsg; pos += 5; pos = octstr_search(buffer, octstr_imm(","), pos); if(pos == -1) goto nomsg; pos++; /* The message length is after the comma */ pos = octstr_parse_long(&len, buffer, pos, 10); if(pos == -1) goto nomsg; /* skip the spaces and line return */ while( isspace(octstr_get_char(buffer, pos))) pos++; /* skip the SMSC address on some modem types */ if((strcmp(smsc->at_modemtype, WAVECOM) == 0) || (strcmp(smsc->at_modemtype, SIEMENS) == 0) || (strcmp(smsc->at_modemtype, ERICSSON) == 0) || (strcmp(smsc->at_modemtype, NOKIAPHONE) == 0) ) { tmp = hexchar(octstr_get_char(buffer, pos))*16 + hexchar(octstr_get_char(buffer, pos+1)); if (tmp < 0) goto nomsg; tmp = 2 + tmp * 2; pos += tmp; } /* check if the buffer is long enough to contain the full message */ if( octstr_len(buffer) < len * 2 + pos) goto nomsg; /* copy the PDU then remove it from the input buffer*/ *pdu = octstr_copy(buffer, pos, len*2); octstr_delete(buffer, 0, pos+len*2); return 1; nomsg: return 0;}/****************************************************************************** * Decode a raw PDU into a Msg */static Msg *pdu_decode(Octstr *data) { int type; Msg *msg = NULL; /* Get the PDU type */ type = octstr_get_char(data, 1) & 3; switch(type) { case AT_DELIVER_SM: msg = pdu_decode_deliver_sm(data); break; /* Add other message types here: */ } return msg;}/****************************************************************************** * Decode a DELIVER PDU */static Msg *pdu_decode_deliver_sm(Octstr *data) { int len, pos, i; char origaddr[21]; int udhi, dcs, udhlen; Octstr *origin = NULL; Octstr *udh = NULL; Octstr *text = NULL, *tmpstr; Octstr *pdu = NULL; Msg *message = NULL; struct universaltime mtime; /* time structure */ long stime; /* time in seconds */ /* Note: some parts of the PDU are not decoded because they are * not needed for the Msg type. */ /* convert the pdu to binary format for ease of processing */ pdu = convertpdu(data); /* UDH Indicator */ udhi = (octstr_get_char(pdu, 0) & 64) >> 6; /* originating address */ len = octstr_get_char(pdu, 1); pos = 3; for(i=0; i<len; i+=2, pos++) { origaddr[i] = (octstr_get_char(pdu, pos) & 15) + 48 ; origaddr[i+1] = (octstr_get_char(pdu, pos) >> 4) + 48; } origaddr[i] = '\0'; origin = octstr_create_from_data(origaddr, len); /* skip the PID for now */ pos++; /* DCS */ dcs = octstr_get_char(pdu, pos); pos++; /* get the timestamp */ mtime.year = octstr_get_char(pdu, pos) + 1900; pos++; mtime.month = octstr_get_char(pdu, pos); pos++; mtime.day = octstr_get_char(pdu, pos); pos++; mtime.hour = octstr_get_char(pdu, pos); pos++; mtime.minute = octstr_get_char(pdu, pos); pos++; mtime.second = octstr_get_char(pdu, pos); pos++; /* time zone: */ /* XXX handle negative time zones */ mtime.hour += octstr_get_char(pdu, pos); pos++; stime = date_convert_universal(&mtime); /* get data length */ len = octstr_get_char(pdu, pos); pos++; /* if there is a UDH */ udhlen = 0; if(udhi) { udhlen = octstr_get_char(pdu, pos); pos++; udh = octstr_copy(pdu, pos, udhlen); pos += udhlen; len -= udhlen +1; } /* build the message */ message = msg_create(sms); if (!dcs_to_fields(&message, dcs)) { /* XXX Should reject this message ? */ debug("AT", 0, "Invalid DCS"); dcs_to_fields(&message, 0); } /* deal with the user data -- 7 or 8 bit encoded */ tmpstr = octstr_copy(pdu,pos,len); if(message->sms.coding == DC_8BIT || message->sms.coding == DC_UCS2) { text = octstr_duplicate(tmpstr); } else { int offset=0; text = octstr_create(""); if (udhi && message->sms.coding == DC_7BIT) { int nbits; nbits = (udhlen + 1)*8; offset = (((nbits/7)+1)*7-nbits)%7; /* Fill bits for UDH to septet boundary */ } decode7bituncompressed(tmpstr, len, text, offset); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -